This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Cmd+Shift+Enter.

##all viruses - target and off target

library(tidyverse)
── Attaching core tidyverse packages ─── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.5.1     ✔ tibble    3.2.1
✔ lubridate 1.9.4     ✔ tidyr     1.3.1
✔ purrr     1.0.4     ── Conflicts ───────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(ggpubr)
library(tidyplots)

Attaching package: ‘tidyplots’

The following object is masked from ‘package:ggpubr’:

    gene_expression
library(ggthemes)
library(scales)

Attaching package: ‘scales’

The following object is masked from ‘package:purrr’:

    discard

The following object is masked from ‘package:readr’:

    col_factor

Figure 1 - linear model

Read-in data

#Linear model for TE data - separated by virus
#November 2024

#viral read depth
#use bowtie2 data

library(tidyverse)
library(broom)
library(boot)

####read counts/normalised read counts####

#metadata

metadata <-
  read.csv(
    "metadata/sampleIDs_TESpikeIn.csv",
    header = TRUE
  )

metadata2 <- metadata |>
  select(Sample.ID, Number.of.read.pairs..quality.adaptor.trimmed.) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)

#import and combine read count files
#deduplicated and non-deduplicated

counts_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_bt_all <- rbind(counts_dedup_bt, counts_nodedup_bt)

counts_reads <- left_join(counts_bt_all, metadata2, by = "Sample_id")

####read depths####

#import and combine read depth files

depth_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

depth_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

Format data


depths_bt_all <- rbind(depth_dedup_bt, depth_nodedup_bt)

depths_reads <- left_join(depths_bt_all, metadata2, by = "Sample_id") |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  ,
  .default = "RNA"
  ))

####linear model for spike in viruses - mean read depth####

depths_reads_sub <- depths_reads |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  filter(type == "dedup_TE") |>
  mutate(log_depth = log10(mean_depth)) |>
  mutate(log_viral_load = log10(Viral.load))

#inspect data
hist(depths_reads_sub$mean_depth)
hist(depths_reads_sub$Viral.load)
hist(depths_reads_sub$log_depth)
hist(depths_reads_sub$log_viral_load)

summary(depths_reads_sub$log_depth)
summary(depths_reads_sub$log_viral_load)

model

#all viruses together

lm1 <-
  glm(log_depth ~ log_viral_load * virus,
      data = depths_reads_sub,
      family = "gaussian")

summary(lm1)

glm.diag.plots(lm1)

pred <- predict(lm1, type = "response")

rsq <- function (x, y) {
  cor(x, y) ^ 2
}

rsq(depths_reads_sub$log_depth, pred)

##split by viruses

cols <- c("#4477AA",
          "#66CCEE",
          "#228833",
          "#CCBB44",
          "#EE6677",
          "#AA3377")

facet_names <- c(
  "Human_adenovirus_40" = "Human adenovirus 40",
  "Human_betaherpesvirus" = "Human betaherpesvirus",
  "Human_respiratory_syncytial_virus" = "Human respiratory syncytial virus",
  "Influenza_B_virus" = "Influenza B virus",
  "Mammalian_orthoreovirus3" = "Mammalian orthoreovirus 3",
  "Zika_virus" = "Zika virus"
)

virus <- (unique(depths_reads_sub$virus)) %>%
  rep(., each = 2) %>%
  data.frame()

list_models <- 
  depths_reads_sub |>
  group_split(virus) |>
  map( ~ lm(log_depth ~ log_viral_load, data = .))

lm_tidy <- 
  map(list_models, broom::tidy) %>%
  do.call(rbind.data.frame, .) %>%
  cbind(virus, .) %>%
  rename(virus = ".") %>%
  select(virus, term, estimate) %>%
  pivot_wider(names_from = "term", values_from = "estimate")

lm_summary <- depths_reads_sub |>
  group_by(virus) |>
  summarise(
    Intercept = lm(log_depth ~ log_viral_load)$coefficients[1],
    Coeff_x1 = lm(log_depth ~ log_viral_load)$coefficients[2],
    R2 = summary(lm(log_depth ~ log_viral_load))$r.squared,
    pvalue = summary(lm(log_depth ~ log_viral_load))$coefficients["log_viral_load", 4]
  )

lm_combined <- 
  left_join(lm_tidy, lm_summary, by = "virus")

Make plot

Final plot

#ggsave("figures/compare_spike_ins_atcc/model_readdepth_dedup.png")

ggsave("figures/manuscript_figure_2025/PDF/Figure_1.pdf",
       width = 8,
       height = 5)

ggsave("figures/manuscript_figure_2025/PNG/Figure_1.png",
       width = 8,
       height = 5)

——————–

Figure S1

Read-in data / Make plots

#metadata

metadata <-
  read.csv(
    "metadata/sampleIDs_TESpikeIn.csv",
    header = TRUE
  )

metadata2 <- metadata |>
  select(Sample.ID, Number.of.read.pairs..quality.adaptor.trimmed.) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)

#import and combine read count files
#deduplicated and non-deduplicated

counts_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_bt_all <- rbind(counts_dedup_bt, counts_nodedup_bt)

counts_reads <- left_join(counts_bt_all, metadata2, by = "Sample_id")

#normalise by both raw read count and genome length - should be the same as mean read depth

counts_reads_norm <- counts_reads |>
  mutate(norm_counts1 = matched / QC_reads) |>
  mutate(norm_counts2 = matched / QC_reads / length) |>
  mutate(norm_counts3 = matched / length) |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  .default = "RNA"
  ))

####compare library capture pool####

cols3 <- c("#228833", "#AA3377")

facet_names <- c("dedup_TE" = "Deduplicated",
                 "nodedup_TE" = "Non-Deduplicated")

metadata3 <- 
  metadata |>
  select(Sample.ID, Pool.for.sequencing) |>
  rename(Sample_id = Sample.ID) |>
  rename(Pool = Pool.for.sequencing)

counts_pool <- left_join(counts_reads_norm, metadata3, by = "Sample_id")

Make plots


pool_counts_sum <- 
  counts_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = as.character(Viral.load),
    y = log10(matched),
    colour = Pool
  )) +
  geom_boxplot() +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    # axis.title.x = element_blank(),
    # axis.text.x = element_blank(),
    legend.title = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  ylab("Log (Viral Reads)") + xlab("Genome copies") +
  scale_color_manual(values = cols3, labels = c("Pool 1", "Pool 2")) + 
  scale_x_discrete(labels = c(bquote(10^{2}), bquote(10^{3}), bquote(10^{5})))
  

# pool_readcounts_norm <- 
#   counts_pool |>
#   filter(Background != "p6") |>
#   filter(Background != "control") |>
#   ggplot(aes(x = virus, y = log10(norm_counts1))) +
#   geom_boxplot() +
#   facet_grid(Pool ~ type) +
#   theme_few() +
#   theme(
#     axis.title.x = element_blank(),
#     # axis.text.x = element_blank(),
#     axis.title.y = element_text(size = 10),
#     panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
#     panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
#   ) +
#   ylab("log10(viral reads/cleaned reads)")

pool_norm1_sum <- 
  counts_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = as.character(Viral.load),
    y = log10(norm_counts1),
    colour = Pool
  )) +
  geom_boxplot() +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    # axis.title.x = element_blank(),
    # axis.text.x = element_blank(),
    legend.title = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray") 
  ) +
  ylab("Log (viral reads/cleaned reads)") + xlab("Genome copies") +
  scale_color_manual(values = cols3, labels = c("Pool 1", "Pool 2")) + 
    scale_x_discrete(labels = c(bquote(10^{2}), bquote(10^{3}), bquote(10^{5})))

# pool_readcounts_norm2 <- 
#   counts_pool |>
#   filter(Background != "p6") |>
#   filter(Background != "control") |>
#   ggplot(aes(x = virus, y = log10(norm_counts2))) +
#   geom_boxplot() +
#   facet_grid(Pool ~ type) +
#   theme_few() +
#   theme(
#     axis.title.x = element_blank(),
#     # axis.text.x = element_blank(),
#     axis.title.y = element_text(size = 10),
#     panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
#     panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
#   ) +
#   ylab("log10(viral reads/cleaned reads/genome length)")


pool_norm2_sum <- 
  counts_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = as.character(Viral.load),
    y = norm_counts2,
    colour = Pool
  )) +
  geom_boxplot() +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    # axis.title.x = element_blank(),
    # axis.text.x = element_blank(),
    legend.title = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  ylab("Log (viral reads/cleaned reads/genome length)") + xlab("Genome copies") +
  scale_color_manual(values = cols3, labels = c("Pool 1", "Pool 2")) + 
    scale_x_discrete(labels = c(bquote(10^{2}), bquote(10^{3}), bquote(10^{5})))


#import and combine read depth files

depth_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

depth_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

depths_bt_all <- rbind(depth_dedup_bt, depth_nodedup_bt)

depths_reads <- 
  left_join(depths_bt_all, metadata2, by = "Sample_id") |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  .default = "RNA"
  ))

depths_pool <- left_join(depths_reads, metadata3, by = "Sample_id")

# pool_readdepths <- 
#   depths_pool |>
#   filter(Background != "p6") |>
#   filter(Background != "control") |>
#   ggplot(aes(x = virus, y = log10(mean_depth))) +
#   geom_boxplot() +
#   facet_grid(Pool ~ type) +
#   theme_few() +
#   theme(
#     axis.title.x = element_blank(),
#     axis.text.x = element_text(angle = 45, hjust = 1),
#     axis.title.y = element_text(size = 10),
#     panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
#     panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
#   ) +
#   ylab("Log (mean read depth)")

pool_depths_sum <-
  depths_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = as.character(Viral.load),
    y = log10(mean_depth),
    colour = Pool
  )) +
  geom_boxplot() +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    # axis.title.x = element_blank(),
    # axis.text.x = element_blank(),
    legend.title = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  ylab("Log (mean read depth)") +
  xlab("Genome copies") + 
  scale_x_discrete(labels = c(bquote(10^{2}), bquote(10^{3}), bquote(10^{5}))) +
  scale_color_manual(values = cols3, labels = c("Pool 1", "Pool 2"))

Final plot

ggarrange(
  pool_counts_sum,
  pool_depths_sum,
  nrow = 1,
  ncol = 2,
  common.legend = TRUE, 
  align = "hv"
)


#ggsave("figures/compare_spike_ins_atcc/pool_compare_viruses_sum.png",width=10,height=7)

ggsave("figures/manuscript_figure_2025/PDF/Figure_S1.pdf",
       width = 12,
       height = 4)

ggsave("figures/manuscript_figure_2025/PNG/Figure_S1.png",
       width = 12,
       height = 4)

——————–

Figure S2

Read counts

### Read-in data

#ATCC genomes updated version
#October 2024

#viral load vs read count normalised using different methods, comparing deduplicated and non-deduplicated
#use bowtie2 data

####read counts/normalised read counts####

#metadata

metadata <- read.csv("metadata/sampleIDs_TESpikeIn.csv", header = TRUE)

metadata2 <- metadata |>
  select(Sample.ID, Number.of.read.pairs..quality.adaptor.trimmed.) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)

#import and combine read count files
#deduplicated and non-deduplicated

counts_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_bt_all <- rbind(counts_dedup_bt, counts_nodedup_bt)

counts_reads <- left_join(counts_bt_all, metadata2, by = "Sample_id")

#normalise by both raw read count and genome length - should be the same as mean read depth

counts_reads_norm <- counts_reads |>
  mutate(norm_counts1 = matched / QC_reads) |>
  mutate(norm_counts2 = matched / QC_reads / length) |>
  mutate(norm_counts3 = matched / length) |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  .default = "RNA"
  ))

Read depths

depth_nodedup_bt <-
  read_tsv(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv"
  )
Rows: 95 Columns: 12── Column specification ───────────────────────────────────
Delimiter: "\t"
chr (5): virus, Sample_id, Background, mapper, type
dbl (7): Viral load, mean_depth, median_depth, min, max...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Format data

#change labels in facet plots

facet_names <- c("dedup_TE" = "Deduplicated",
                 "nodedup_TE" = "Non-Deduplicated")

cols <- c("#4477AA",
          "#66CCEE",
          "#228833",
          "#CCBB44",
          "#EE6677",
          "#AA3377")

Make plots

read_depths <- 
  depths_reads |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(mean_depth),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 0, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  scale_linetype_manual(values=c(2, 1)) +
  scale_linetype_manual(values=c("dotted", "solid")) + 
  ylab("Log (mean read depth)") +
  xlab("Genome copies") + 
  scale_x_log10(labels = scales::trans_format("log10", scales::label_math()))
Scale for linetype is already present.
Adding another scale for linetype, which will replace the
existing scale.

Final plot

——————–

Figure S3

reads_plot <- 
  reads_viral_all |>
  group_by(Background, Sample_id, Viral.load, type) |>
  summarise(
    total_reads = (QC_reads * 2),
    viral_reads = total_virus_reads,
    ATCC_reads = sum(matched),
    prop_ATCC = ATCC_reads / total_reads,
    prop_viral = total_virus_reads / total_reads,
    diff = viral_reads - ATCC_reads
  ) |>
  unique()
Warning: Returning more (or less) than 1 row per `summarise()` group was deprecated in dplyr 1.1.0.
Please use `reframe()` instead.
When switching from `summarise()` to `reframe()`, remember that `reframe()` always returns an ungrouped data frame and adjust accordingly.`summarise()` has grouped output by 'Background', 'Sample_id', 'Viral.load', 'type'. You can override using the `.groups` argument.

Make plots

Final plot

——————–

No longer required? Figure S4

Make plots

####read counts/depths split by background####

#change labels in facet plots

facet_names_bg <- c(
  "dedup_TE" = "Deduplicated",
  "nodedup_TE" = "Non-Deduplicated",
  "p2" = "M1",
  "p8" = "M2"
)

#break down by Background x virus

background_counts_reads <- 
  counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(matched),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid(Background ~ type, labeller = as_labeller(facet_names_bg)) +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels =
      c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
      )
  ) +
  scale_x_log10(labels = scales::label_log10()) +
  ylab("Log (Viral Reads)")

backgrounds_counts_reads_norm <- 
  counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(norm_counts1),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid(Background ~ type, labeller = as_labeller(facet_names_bg)) +
  theme_bw() +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  scale_x_log10(label = scales::label_log10()) +
  ylab("Log (viral reads/cleaned reads)")

backgrounds_counts_reads_norm2 <- 
  counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(norm_counts2),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid(Background ~ type, labeller = as_labeller(facet_names_bg)) +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  scale_x_log10(labels = scales::label_log10()) +
  ylab("Log (viral reads/cleaned reads/genome length)")

background_read_depths <- 
  depths_reads |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(mean_depth),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid(Background ~ type, labeller = as_labeller(facet_names_bg)) +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray"),
    axis.title.y = element_text(size = 10),
    legend.title = element_blank()
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  scale_x_log10(label = scales::label_log10()) +
  ylab("Log (mean read depth)")

Final plot

——————–

——————–

>>> Figure 2: plots of TE experiment data - genome coverage & per site coverage

Read-in data

counts_nodedup_bt <-
  read_tsv(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv"
  )
Rows: 96 Columns: 9── Column specification ───────────────────────────────────
Delimiter: "\t"
chr (5): virus, Sample_id, Background, mapper, type
dbl (4): length, matched, unmatched, Viral load
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Format data

persite_coverage_nodedup <- 
  nodedup_per_site |>
  rename(Viral.load = `Viral load`) |>
  group_by(Sample_id, virus, Viral.load, Background, type) |>
  filter(coverage > 0) |>
  summarise(genome_coverage = n()) |>
  left_join(lengths) |>
  mutate(percent_coverage = genome_coverage / length)
`summarise()` has grouped output by 'Sample_id', 'virus', 'Viral.load', 'Background'. You can override using the `.groups` argument.Joining with `by = join_by(virus)`

Make plots

Final plot

——————–

——————–

Figure S4

Final plot

ggsave("figures/manuscript_figure_2025/PDF/Figure_S4.pdf",
       width=15,
       height=10)

ggsave("figures/manuscript_figure_2025/PNG/Figure_S4.png",
       width=15,
       height=10)

——————–

Figure S5

####Final plot


ggsave("figures/manuscript_figure_2025/PDF/Figure_S5.pdf",
       width=15,
       height=10)

ggsave("figures/manuscript_figure_2025/PNG/Figure_S5.png",
       width=15,
       height=10)

——————–

Figure S6

####Final plot


ggsave("figures/manuscript_figure_2025/PDF/Figure_S6.pdf",
       width=15,
       height=10)

ggsave("figures/manuscript_figure_2025/PNG/Figure_S6.png",
       width=15,
       height=10)

——————–

Figure S7

HBV <- 
persite_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  filter(type == "dedup_TE") |>
  filter(virus == "Human_betaherpesvirus") |>
  rename(Viral.load = `Viral load`) |>
  ggplot(aes(x = site, y = coverage, fill = Background)) +
  geom_col() +
  facet_wrap(Viral.load ~ Sample_id, label = label_parsed) +
  ylab("Coverage") +
  ggtitle("Human Betaherpesvirus (deduplicated)") +
  guides(fill = guide_legend(title = "Background")) +
 theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 30, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_y_log10() +
  scale_fill_manual(values = cols2, labels = c("M1", "M2"))

####Final plot


ggsave(plot = HBV, file="figures/manuscript_figure_2025/PDF/Figure_S7.pdf",
       width=15,
       height=10,
       dpi = 600)

ggsave(plot = HBV, file="figures/manuscript_figure_2025/PNG/Figure_S7.png",
       width=15,
       height=10)

——————–

Figure S8

ggarrange(FLU_ME1, FLU_ME2, ncol = 2, common.legend = TRUE)
Warning: log-10 transformation introduced infinite values.Warning: Removed 3867 rows containing missing values or values
outside the scale range (`geom_col()`).Warning: log-10 transformation introduced infinite values.Warning: Removed 3867 rows containing missing values or values
outside the scale range (`geom_col()`).Warning: log-10 transformation introduced infinite values.Warning: Removed 996 rows containing missing values or values
outside the scale range (`geom_col()`).

####Final plot


ggsave("figures/manuscript_figure_2025/PDF/Figure_S8.pdf",
       width=20,
       height=12,
       dpi=600)

ggsave("figures/manuscript_figure_2025/PNG/Figure_S8.png",
       width=20,
       height=12)

——————–

Figure S9


REO_ME1 <- 
  persite_norm |>
  filter(virus == "Mammalian_orthoreovirus3") |>
  filter(type == "dedup_TE") |>
  filter(Background == "p2") |>
  rename(Viral.load = `Viral load`) |>
  ggplot(aes(
    x = site,
    y = coverage,
    fill = as.character(Viral.load)
  )) +
  geom_col() +
  facet_grid(seg ~ Sample_id) +
  ylab("Coverage") +
  ggtitle("Mammalian orthoreovirus 3 (Background M1 deduplicated)") +
  guides(fill = guide_legend(title = "Viral load")) +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 30, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top",
    panel.grid.major = element_line(linewidth = 0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth = 0.1, color = "lightgray")
  ) +
  scale_y_log10() +
  scale_fill_manual(values = cols4,
                    label = c(
                      expression("10" ^ "2"),
                      expression("10" ^ "3"),
                      expression("10" ^ "5")
                    ))

REO_ME2 <- 
  persite_norm |>
  filter(virus == "Mammalian_orthoreovirus3") |>
  filter(type == "dedup_TE") |>
  filter(Background == "p8") |>
  rename(Viral.load = `Viral load`) |>
  ggplot(aes(
    x = site,
    y = coverage,
    fill = as.character(Viral.load)
  )) +
  geom_col() +
  facet_grid(seg ~ Sample_id) +
  ylab("Coverage") +
  ggtitle("Mammalian orthoreovirus 3 (Background M2 deduplicated)") +
  guides(fill = guide_legend(title = "Viral load")) +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 30, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top",
    panel.grid.major = element_line(linewidth = 0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth = 0.1, color = "lightgray")
  ) + scale_y_log10() +
  scale_fill_manual(values = cols4,
                    label = c(
                      expression("10" ^ "2"),
                      expression("10" ^ "3"),
                      expression("10" ^ "5")
                    ))

ggarrange(REO_ME1, REO_ME2, ncol = 2, common.legend = TRUE)
Warning: log-10 transformation introduced infinite values.Warning: Removed 2181 rows containing missing values or values
outside the scale range (`geom_col()`).Warning: log-10 transformation introduced infinite values.Warning: Removed 2181 rows containing missing values or values
outside the scale range (`geom_col()`).Warning: log-10 transformation introduced infinite values.Warning: Removed 934 rows containing missing values or values
outside the scale range (`geom_col()`).

####Final plot

ggsave("figures/manuscript_figure_2025/PDF/Figure_S9.pdf",
       width=20,
       height=12,
       dpi=600)

ggsave("figures/manuscript_figure_2025/PNG/Figure_S9.png",
       width=20,
       height=12,
       dpi=600)

——————–

>>>> Figure 3: all viruses - target and off target

Read-in data


# read in metadata

metadata <-
  read.csv("metadata/sampleIDs_TESpikeIn.csv", header = TRUE)

metadata2 <-
  metadata |>
  select(
    Sample.ID,
    Background.sample,
    Viral.load,
    Number.of.read.pairs..quality.adaptor.trimmed.
  ) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)

#import viral reads mapped (to calculate proportions)

viral_reads_dedup <-
  read.csv(
    "data_TE/total_virus_mapped_reads_per_sample_dedup_atcc_ref_20241108.csv",
    header = TRUE
  )

viral_reads_nodedup <-
  read.csv(
    "data_TE/total_virus_mapped_reads_per_sample_nodedup_atcc_ref_20241108.csv",
    header = TRUE
  )

#import contingency tables

contingency_dedup <-
  read.csv(
    "data_TE/contingency_table_mapped_virus_reads_per_family_genus_sample_dedup_atcc_ref_20241106.csv",
    header = TRUE
  )

contingency_nodedup <-
  read.csv(
    "data_TE/contingency_table_mapped_virus_reads_per_family_genus_sample_nodedup_atcc_ref_20241106.csv",
    header = TRUE
  )

contaminants <-
  c("Betacoronavirus", "Alphainfluenzavirus", "Gammaretrovirus")

Format data


# pivot longer  
dedup_long <-
  contingency_dedup |>
  filter(!genus %in% contaminants) |>
  filter(genus != "NA") |>
  pivot_longer(cols = A:P,
               names_to = "Sample_id",
               values_to = "count") |>
  mutate(
    target = case_when(
      genus == "Cyclovirus" ~ "off_target",
      genus == "Cardiovirus" ~ "off_target",
      genus == "Kobuvirus" ~ "off_target",
      .default = "on_target"
    )
  ) |>
  mutate(genome_structure = case_when((genus == "Mastadenovirus" |
                                         genus == "Cytomegalovirus") ~ "DNA",
                                      .default = "RNA"
  ))

no_dedup_long <- contingency_nodedup |>
  filter(!genus %in% contaminants) |>
  filter(genus != "NA") |>
  pivot_longer(cols = A:P,
               names_to = "Sample_id",
               values_to = "count") |>
  mutate(
    target = case_when(
      genus == "Cyclovirus" ~ "off_target",
      genus == "Cardiovirus" ~ "off_target",
      genus == "Kobuvirus" ~ "off_target",
      .default = "on_target"
    )
  ) |>
  mutate(genome_structure = case_when((genus == "Mastadenovirus" |
                                         genus == "Cytomegalovirus") ~ "DNA",
                                      .default = "RNA"
  ))

metadata_dedup <- left_join(dedup_long, metadata2, by = "Sample_id")

dedup_viral_reads <-
  left_join(metadata_dedup, viral_reads_dedup, by = "Sample_id") |>
  mutate(total_reads = QC_reads * 2) |>
  mutate(prop_total = count / total_reads) |>
  mutate(prop_viral = count / total_virus_reads)

metadata_no_dedup <- left_join(no_dedup_long, metadata2, by = "Sample_id")

nodedup_viral_reads <-
  left_join(metadata_no_dedup, viral_reads_nodedup, by = "Sample_id") |>
  mutate(total_reads = QC_reads * 2) |>
  mutate(prop_total = count / total_reads) |>
  mutate(prop_viral = count / total_virus_reads)

Make plots

Dedup – viral reads, prop all reads, and prop viral reads

Final plot

…………………….

…………………….

—-Genome medicine results—-

Figure S10

Read-in data



####read counts/normalised read counts####

#import and combine read count files

gm_readcount_dedup <-
  read.table(
    "data_genome_medicine/genome_medicine_TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

gm_readcount_nodedup <-
  read.table(
    "data_genome_medicine/genome_medicine_TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

gm_counts_all <- rbind(gm_readcount_dedup, gm_readcount_nodedup)

read counts

read depth

#import and combine read depth files

depth_dedup_gm <-
  read.table(
    "data_genome_medicine/genome_medicine_TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

depth_nodedup_gm <-
  read.table(
    "data_genome_medicine/genome_medicine_TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

depths_gm_all <- rbind(depth_dedup_gm, depth_nodedup_gm)

——————–

Figure S11

Read-in data

####genome coverage####

unzip(zipfile = "data_genome_medicine/genome_medicine_TE_sequencing_experiment_readdepth_per_site_sample_and_virus_bowtie2_dedup_atcc_ref.tsv.zip", exdir = "data_genome_medicine/")

dedup_per_site <-
  read.table(
    "data_genome_medicine/genome_medicine_TE_sequencing_experiment_readdepth_per_site_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

file.remove("data_genome_medicine/genome_medicine_TE_sequencing_experiment_readdepth_per_site_sample_and_virus_bowtie2_dedup_atcc_ref.tsv")
[1] TRUE
#View(dedup_per_site)

counts_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

#add length column from read depth file to per site file

lengths <- 
  counts_dedup_bt |>
  select(virus,length) |>
  distinct()

#calculate genome coverage

coverage <- 
  dedup_per_site |>
  group_by(sample_id, virus, Viral.load, Replicate) |>
  filter(coverage > 0) |>
  summarise(genome_coverage = n()) |>
  left_join(lengths) |>
  mutate(percent_coverage = genome_coverage / length)
`summarise()` has grouped output by 'sample_id', 'virus', 'Viral.load'. You can override using the `.groups` argument.Joining with `by = join_by(virus)`
coverage |>
  filter(Viral.load != 0) |>
  ggplot(aes(x = virus, y = percent_coverage)) +
  geom_boxplot(outlier.shape = NA) +
  geom_point(position = position_dodge(width = .75)) +
  facet_grid( ~ as.character(Viral.load)) +
  theme_bw() +
  theme(axis.title.y = element_text(size = 10)) +
  ylab("Genome coverage") +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    axis.text.x = element_text(angle = 45, hjust = 1),
    axis.title.y = element_text(size = 15),
    axis.text = element_text(size = 12),
    strip.text = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top",
    panel.grid.major = element_line(linewidth = 0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth = 0.1, color = "lightgray")
  ) +
  scale_y_continuous(limits = c(0, 1)) +
    scale_x_discrete(
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  )


#ggsave("/Users/laura/Dropbox/glasgow/github/te_ug_rodents/figures/genome_medicine/all_genome_coverage.png",width=14,height=6)

#ggsave("/Users/laura/Dropbox/glasgow/github/te_ug_rodents/figures/manuscript_figures_pdf/FigureS12.pdf",width=20,height=6)

*** Final plot ***

#PDF
ggsave(
  "figures/manuscript_figure_2025/PDF/Figure_S11.pdf",
  width = 14,
  height = 6
)

#PNG
ggsave(
  "figures/manuscript_figure_2025/PNG/Figure_S11.png",
  width = 14,
  height = 6
)

——————–

Figure S12

*** Final plot ***

ggsave("figures/manuscript_figure_2025/PDF/Figure_S12.pdf",
       width=12,
       height=10)

ggsave("figures/manuscript_figure_2025/PNG/Figure_S12.png",
       width=12,
       height=10)

…………………….

—-Kobuvirus / Cardiovirus results—-

Figure S13


kobu_depth <-
  read.table(
    "data_kobuvirus/kobuvirus_TE_polyomics_readdepth_20241007.tsv",
    sep = "\t",
    header = TRUE
  ) %>%
  select(!expt) %>%
  select(!Number.of.paired.end.reads..QT.)

cardio_depth <-
  read.table(
    "data_cardiovirus/cardiovirus_denovo_bowtie2_read_depth_per_sample_dedup.tsv",
    sep = ",",
    header = TRUE
  )

cardio_depth_poly <- 
  read.table(
    "data_cardiovirus/cardiovirus_denovo_bowtie2_readdepth_per_sample_dedup_polyomics.tsv",
    sep = ",",
    header = TRUE
  ) |>
  select(-contig_name) |>
  filter(Background %in% c("S18", "S19", "S43")) |>
  select(-Background) |>
  separate(Sample_id, into = c(NA, NA, "Background"), sep = "-", remove = FALSE)

depth_both <- rbind(kobu_depth, cardio_depth, cardio_depth_poly) |>
  mutate(Viral.load = ifelse(is.na(Viral.load), 0, Viral.load))

depth_both$type <- depth_both$type |>
  case_match("dedup_TE" ~ "dedup",
             "dedup_polyomics" ~ "dedup",
             .default = depth_both$type)

depth_both$Sample_id <- depth_both$Sample_id |>
  case_match("RNA-Msp-p2" ~ "M1",
             "RNA-Msp-p8" ~ "M2",
             "RNA-Msp-p6" ~ "M3",
             .default = depth_both$Sample_id
             )

depth_both$virus <- depth_both$virus |>
  case_match("cardiovirus" ~ "Cardiovirus",
             "k97_19971" ~ "Kobuvirus",
             .default = depth_both$virus
             )

cols2 <- c("#BB5566", "#004488")

coverage_labels <- c(
  "k97_19971" = "Kobuvirus",
  "cardiovirus" = "Cardiovirus",
  "p2" = "M1",
  "p8" = "M2"
)

*** Final plot ***


depth_both$Viral.load <- factor(depth_both$Viral.load, labels = c("Shotgun",
    "10^{2}", 
    "10^{3}", 
    "10^{5}"
    ))


# depth_both |>
#   filter(Background != "p6") |>
#   filter(type == "dedup") |>
#   filter(mapper == "bowtie2") |>
#   filter(Viral.load != "NA") |>
#   ggplot(aes(
#     x = Viral.load,
#     y = (mean_depth),
#     colour = Background
#   )) +
#   geom_point() +
#  theme_few() +
#   theme(
#     axis.title.x = element_text(size = 12),
#     axis.title.y = element_text(size = 12),
#     legend.title = element_blank(),
#     legend.position = "none", 
#     panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
#     panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
#   ) +  
#   facet_grid(Background ~ virus, labeller = as_labeller(coverage_labels)) +
#   scale_color_manual(values = cols2) +
#   ylab("Mean read depth") +
#     xlab("Spike-in viral load (gc/ml)") +
#    scale_x_log10(labels = scales::trans_format("log10",
#                                         scales::label_math())) + 
#   scale_y_log10(labels = scales::trans_format("log10",
#                                         scales::label_math()))

# replotting S13 in similar way to S14
depth_both %>%
  filter(Background != "p6") |>
  filter(type == "dedup") |>
  filter(mapper == "bowtie2") |>
  # filter(Viral.load != "NA") |>
  ggplot(aes(x = Sample_id, y = mean_depth, color = Background)) +
  geom_point() +
  ylab("Mean read depth") +
  xlab("Sample ID") +
  facet_grid(virus ~ Viral.load,
             scales = "free_x",
             label = label_parsed) +
  scale_color_manual(values = cols2, labels = c("M1", "M2")) +
 theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "right", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  )+
  scale_y_log10(labels = scales::trans_format("log10",
                                        scales::label_math()))


ggsave("figures/manuscript_figure_2025/PDF/Figure_S13_v2.pdf",
       width=8,
       height=4)

ggsave("figures/manuscript_figure_2025/PNG/Figure_S13_v2.png",
       width=8,
       height=4)

——————–

Figure S14


kobu_per_site <-
  read.table(
    "data_kobuvirus/kobuvirus_TE_polyomics_readdepth_persite_20241007.tsv",
    sep = "\t",
    header = TRUE
  ) %>%
  select(virus,
         seg,
         site,
         coverage,
         n_sites,
         Sample_id,
         Background,
         Viral.load,
         mapper,
         type)

kobu_per_site$Viral.load <- 
  kobu_per_site$Viral.load %>%
  replace_na(., 0)

kobu_per_site$Sample_id <- kobu_per_site$Sample_id %>%
  case_match("RNA-Msp-p2" ~ "M1",
             "RNA-Msp-p8" ~ "M2",
             .default = kobu_per_site$Sample_id)

kobu_per_site$Background <- kobu_per_site$Background %>%
  case_match("p2" ~ "M1",
             "p8" ~ "M2",
             .default = kobu_per_site$Background)

cardio_per_site <-
  read.table(
    "data_cardiovirus/cardiovirus_denovo_bowtie2_read_depth_per_site_and_sample_dedup.tsv",
    sep = ",",
    header = TRUE
  )

cardio_polyomics_per_site <-
  read.table(
    "data_cardiovirus/cardiovirus_denovo_bowtie2_readdepth_per_site_sample_dedup_polyomics.tsv",
    sep = ",",
    header = TRUE
  ) %>%
  select(!contig_name)

#View(cardio_polyomics_per_site)

cardio_TE_polyomics <-
  full_join(
    cardio_per_site,
    cardio_polyomics_per_site,
    by = c(
      "virus",
      "seg",
      "site",
      "coverage",
      "n_sites",
      "Sample_id",
      "Background",
      "Viral.load",
      "mapper",
      "type"
    )
  )

cardio_TE_polyomics$Viral.load <- cardio_TE_polyomics$Viral.load %>%
  replace_na(., 0)

drops <-
  c(
    "RNA-Msp-p1",
    "RNA-Msp-p3",
    "RNA-Msp-p4",
    "RNA-Msp-p5",
    "RNA-Msp-p6",
    "RNA-Msp-p7",
    "RNA-Msp-p9"
  )

cardio_TE_polyomics <- cardio_TE_polyomics %>%
  filter(!Sample_id %in% drops)

cardio_TE_polyomics$Sample_id <- cardio_TE_polyomics$Sample_id %>%
  case_match("RNA-Msp-p2" ~ "M1",
             "RNA-Msp-p8" ~ "M2",
             .default = cardio_TE_polyomics$Sample_id)

cardio_TE_polyomics$Background <- cardio_TE_polyomics$Background %>%
  case_match("S18" ~ "M1",
             "S43" ~ "M2",
             "p2" ~ "M1",
             "p8" ~ "M2",
             .default = cardio_TE_polyomics$Background)

persite_both <- rbind(kobu_per_site, cardio_TE_polyomics)

persite_both$type <- persite_both$type %>%
  case_match("dedup_TE" ~ "dedup",
             "dedup_polyomics" ~ "dedup",
             .default = persite_both$type)

#TE data only - compare coverage between backgrounds/viral loads

cols2 <- c("#BB5566", "#004488")

coverage_labels <- c(
  "100" = "10^{2}",
  "1000" = "10^{3}",
  "100000" = "10^{5}",
  "0" = "Shotgun",
  "Kobuvirus" = "Kobuvirus",
  "Cardiovirus" = "Cardiovirus"
)

coverage_labels2 <- c(
  "100" = "10^{2}",
  "1000" = "10^{3}",
  "100000" = "10^{5}",
  "0" = "Shotgun",
  "A" = "A",
  "B" = "B",
  "C" = "C",
  "D" = "D",
  "F" = "F",
  "G" = "G",
  "H" = "H",
  "I" = "I",
  "J" = "J",
  "K" = "K",
  "L" = "L",
  "M" = "M",
  "N" = "N",
  "O" = "O",
  "P" = "P",
  "ME_P1" = "M1",
  "ME_P2" = "M2"
)

kobu_coverage <- kobu_per_site %>%
  filter(mapper == "bowtie2") %>%
  filter(type == "dedup") %>%
  filter(Background != "p6") %>%
  group_by(Sample_id, Viral.load, Background) %>%
  filter(coverage > 0) %>%
  summarise(genome_coverage = n()) %>%
  mutate(percent_coverage = genome_coverage / 8467) %>%
  mutate(virus = "Kobuvirus")
`summarise()` has grouped output by 'Sample_id', 'Viral.load'. You can override using the `.groups` argument.
cardio_coverage <- cardio_TE_polyomics %>%
  filter(Background != "p6") %>%
  group_by(Sample_id, Viral.load, Background) %>%
  filter(coverage > 0) %>%
  summarise(genome_coverage = n()) %>%
  mutate(percent_coverage = genome_coverage / 6945) %>%
  mutate(virus = "Cardiovirus")
`summarise()` has grouped output by 'Sample_id', 'Viral.load'. You can override using the `.groups` argument.
coverage_both <- rbind(kobu_coverage, cardio_coverage)

coverage_both$Viral.load <- factor(coverage_both$Viral.load, labels = c("Shotgun",
    "10^{2}", 
    "10^{3}", 
    "10^{5}"
    ))

*** Final plot ***


coverage_both %>%
  ggplot(aes(x = Sample_id, y = percent_coverage, color = Background)) +
  geom_point() +
  ylab("Genome coverage") +
  xlab("Sample ID") +
  facet_grid(virus ~ (Viral.load),
             scales = "free_x",
             label = label_parsed) +
  scale_color_manual(values = cols2, labels = c("M1", "M2")) +
 theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "right", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) + 
  scale_y_continuous(limits = c(0, 1))

#PDF
ggsave("figures/manuscript_figure_2025/PDF/Figure_S14.pdf", 
       width = 8, 
       height = 4)

#PNG
ggsave("figures/manuscript_figure_2025/PNG/Figure_S14.png", 
       width = 8, 
       height = 4)

——————–

Figure S15

*** Final plot ***

#PDF
ggsave("figures/manuscript_figure_2025/PDF/Figure_S15.pdf",
       width=12,
       height=7)

#PNG
ggsave("figures/manuscript_figure_2025/Png/Figure_S15.png",
       width=12,
       height=7)

Figure S16

*** Final plot ***


#PDF
ggsave("figures/manuscript_figure_2025/PDF/Figure_S16.pdf",
       width=12,
       height=7)


#PNG
ggsave("figures/manuscript_figure_2025/PNG/Figure_S16.png",
       width=12,
       height=7)
LS0tCnRpdGxlOiAidGFyZ2V0X29mZnRhcmdldCIKb3V0cHV0OiBodG1sX25vdGVib29rCmVkaXRvcl9vcHRpb25zOiAKICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lCi0tLQoKVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4gCgpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ21kK1NoaWZ0K0VudGVyKi4gCgpgYGB7cn0KIyNhbGwgdmlydXNlcyAtIHRhcmdldCBhbmQgb2ZmIHRhcmdldAoKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2dwdWJyKQpsaWJyYXJ5KHRpZHlwbG90cykKbGlicmFyeShnZ3RoZW1lcykKbGlicmFyeShzY2FsZXMpCgpgYGAKCiMjIyBGaWd1cmUgMSAtIGxpbmVhciBtb2RlbAoKIyMjIyBSZWFkLWluIGRhdGEKYGBge3J9CiNMaW5lYXIgbW9kZWwgZm9yIFRFIGRhdGEgLSBzZXBhcmF0ZWQgYnkgdmlydXMKI05vdmVtYmVyIDIwMjQKCiN2aXJhbCByZWFkIGRlcHRoCiN1c2UgYm93dGllMiBkYXRhCgpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShicm9vbSkKbGlicmFyeShib290KQoKIyMjI3JlYWQgY291bnRzL25vcm1hbGlzZWQgcmVhZCBjb3VudHMjIyMjCgojbWV0YWRhdGEKCm1ldGFkYXRhIDwtCiAgcmVhZC5jc3YoCiAgICAibWV0YWRhdGEvc2FtcGxlSURzX1RFU3Bpa2VJbi5jc3YiLAogICAgaGVhZGVyID0gVFJVRQogICkKCm1ldGFkYXRhMiA8LSBtZXRhZGF0YSB8PgogIHNlbGVjdChTYW1wbGUuSUQsIE51bWJlci5vZi5yZWFkLnBhaXJzLi5xdWFsaXR5LmFkYXB0b3IudHJpbW1lZC4pIHw+CiAgcmVuYW1lKFNhbXBsZV9pZCA9IFNhbXBsZS5JRCkgfD4KICByZW5hbWUoUUNfcmVhZHMgPSBOdW1iZXIub2YucmVhZC5wYWlycy4ucXVhbGl0eS5hZGFwdG9yLnRyaW1tZWQuKQoKI2ltcG9ydCBhbmQgY29tYmluZSByZWFkIGNvdW50IGZpbGVzCiNkZWR1cGxpY2F0ZWQgYW5kIG5vbi1kZWR1cGxpY2F0ZWQKCmNvdW50c19kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGNvdW50X3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKY291bnRzX25vZGVkdXBfYnQgPC0KICByZWFkLnRhYmxlKAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRjb3VudF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX25vZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKY291bnRzX2J0X2FsbCA8LSByYmluZChjb3VudHNfZGVkdXBfYnQsIGNvdW50c19ub2RlZHVwX2J0KQoKY291bnRzX3JlYWRzIDwtIGxlZnRfam9pbihjb3VudHNfYnRfYWxsLCBtZXRhZGF0YTIsIGJ5ID0gIlNhbXBsZV9pZCIpCgojIyMjcmVhZCBkZXB0aHMjIyMjCgojaW1wb3J0IGFuZCBjb21iaW5lIHJlYWQgZGVwdGggZmlsZXMKCmRlcHRoX2RlZHVwX2J0IDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpkZXB0aF9ub2RlZHVwX2J0IDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9ub2RlZHVwX2F0Y2NfcmVmLnRzdiIsCiAgICBzZXAgPSAiXHQiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmBgYAoKIyMjIyBGb3JtYXQgZGF0YQpgYGB7cn0KCmRlcHRoc19idF9hbGwgPC0gcmJpbmQoZGVwdGhfZGVkdXBfYnQsIGRlcHRoX25vZGVkdXBfYnQpCgpkZXB0aHNfcmVhZHMgPC0gbGVmdF9qb2luKGRlcHRoc19idF9hbGwsIG1ldGFkYXRhMiwgYnkgPSAiU2FtcGxlX2lkIikgfD4KICBtdXRhdGUoZ2Vub21lX3N0cnVjdHVyZSA9IGNhc2Vfd2hlbigoCiAgICB2aXJ1cyA9PSAiSHVtYW5fYWRlbm92aXJ1c180MCIgfAogICAgICB2aXJ1cyA9PSAiSHVtYW5fYmV0YWhlcnBlc3ZpcnVzIgogICkgfiAiRE5BIiwKICAsCiAgLmRlZmF1bHQgPSAiUk5BIgogICkpCgojIyMjbGluZWFyIG1vZGVsIGZvciBzcGlrZSBpbiB2aXJ1c2VzIC0gbWVhbiByZWFkIGRlcHRoIyMjIwoKZGVwdGhzX3JlYWRzX3N1YiA8LSBkZXB0aHNfcmVhZHMgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBmaWx0ZXIodHlwZSA9PSAiZGVkdXBfVEUiKSB8PgogIG11dGF0ZShsb2dfZGVwdGggPSBsb2cxMChtZWFuX2RlcHRoKSkgfD4KICBtdXRhdGUobG9nX3ZpcmFsX2xvYWQgPSBsb2cxMChWaXJhbC5sb2FkKSkKCiNpbnNwZWN0IGRhdGEKaGlzdChkZXB0aHNfcmVhZHNfc3ViJG1lYW5fZGVwdGgpCmhpc3QoZGVwdGhzX3JlYWRzX3N1YiRWaXJhbC5sb2FkKQpoaXN0KGRlcHRoc19yZWFkc19zdWIkbG9nX2RlcHRoKQpoaXN0KGRlcHRoc19yZWFkc19zdWIkbG9nX3ZpcmFsX2xvYWQpCgpzdW1tYXJ5KGRlcHRoc19yZWFkc19zdWIkbG9nX2RlcHRoKQpzdW1tYXJ5KGRlcHRoc19yZWFkc19zdWIkbG9nX3ZpcmFsX2xvYWQpCgpgYGAKCiMjIyMgbW9kZWwKYGBge3J9CiNhbGwgdmlydXNlcyB0b2dldGhlcgoKbG0xIDwtCiAgZ2xtKGxvZ19kZXB0aCB+IGxvZ192aXJhbF9sb2FkICogdmlydXMsCiAgICAgIGRhdGEgPSBkZXB0aHNfcmVhZHNfc3ViLAogICAgICBmYW1pbHkgPSAiZ2F1c3NpYW4iKQoKc3VtbWFyeShsbTEpCgpnbG0uZGlhZy5wbG90cyhsbTEpCgpwcmVkIDwtIHByZWRpY3QobG0xLCB0eXBlID0gInJlc3BvbnNlIikKCnJzcSA8LSBmdW5jdGlvbiAoeCwgeSkgewogIGNvcih4LCB5KSBeIDIKfQoKcnNxKGRlcHRoc19yZWFkc19zdWIkbG9nX2RlcHRoLCBwcmVkKQoKIyNzcGxpdCBieSB2aXJ1c2VzCgpjb2xzIDwtIGMoIiM0NDc3QUEiLAogICAgICAgICAgIiM2NkNDRUUiLAogICAgICAgICAgIiMyMjg4MzMiLAogICAgICAgICAgIiNDQ0JCNDQiLAogICAgICAgICAgIiNFRTY2NzciLAogICAgICAgICAgIiNBQTMzNzciKQoKZmFjZXRfbmFtZXMgPC0gYygKICAiSHVtYW5fYWRlbm92aXJ1c180MCIgPSAiSHVtYW4gYWRlbm92aXJ1cyA0MCIsCiAgIkh1bWFuX2JldGFoZXJwZXN2aXJ1cyIgPSAiSHVtYW4gYmV0YWhlcnBlc3ZpcnVzIiwKICAiSHVtYW5fcmVzcGlyYXRvcnlfc3luY3l0aWFsX3ZpcnVzIiA9ICJIdW1hbiByZXNwaXJhdG9yeSBzeW5jeXRpYWwgdmlydXMiLAogICJJbmZsdWVuemFfQl92aXJ1cyIgPSAiSW5mbHVlbnphIEIgdmlydXMiLAogICJNYW1tYWxpYW5fb3J0aG9yZW92aXJ1czMiID0gIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMiLAogICJaaWthX3ZpcnVzIiA9ICJaaWthIHZpcnVzIgopCgp2aXJ1cyA8LSAodW5pcXVlKGRlcHRoc19yZWFkc19zdWIkdmlydXMpKSAlPiUKICByZXAoLiwgZWFjaCA9IDIpICU+JQogIGRhdGEuZnJhbWUoKQoKbGlzdF9tb2RlbHMgPC0gCiAgZGVwdGhzX3JlYWRzX3N1YiB8PgogIGdyb3VwX3NwbGl0KHZpcnVzKSB8PgogIG1hcCggfiBsbShsb2dfZGVwdGggfiBsb2dfdmlyYWxfbG9hZCwgZGF0YSA9IC4pKQoKbG1fdGlkeSA8LSAKICBtYXAobGlzdF9tb2RlbHMsIGJyb29tOjp0aWR5KSAlPiUKICBkby5jYWxsKHJiaW5kLmRhdGEuZnJhbWUsIC4pICU+JQogIGNiaW5kKHZpcnVzLCAuKSAlPiUKICByZW5hbWUodmlydXMgPSAiLiIpICU+JQogIHNlbGVjdCh2aXJ1cywgdGVybSwgZXN0aW1hdGUpICU+JQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAidGVybSIsIHZhbHVlc19mcm9tID0gImVzdGltYXRlIikKCmxtX3N1bW1hcnkgPC0gZGVwdGhzX3JlYWRzX3N1YiB8PgogIGdyb3VwX2J5KHZpcnVzKSB8PgogIHN1bW1hcmlzZSgKICAgIEludGVyY2VwdCA9IGxtKGxvZ19kZXB0aCB+IGxvZ192aXJhbF9sb2FkKSRjb2VmZmljaWVudHNbMV0sCiAgICBDb2VmZl94MSA9IGxtKGxvZ19kZXB0aCB+IGxvZ192aXJhbF9sb2FkKSRjb2VmZmljaWVudHNbMl0sCiAgICBSMiA9IHN1bW1hcnkobG0obG9nX2RlcHRoIH4gbG9nX3ZpcmFsX2xvYWQpKSRyLnNxdWFyZWQsCiAgICBwdmFsdWUgPSBzdW1tYXJ5KGxtKGxvZ19kZXB0aCB+IGxvZ192aXJhbF9sb2FkKSkkY29lZmZpY2llbnRzWyJsb2dfdmlyYWxfbG9hZCIsIDRdCiAgKQoKbG1fY29tYmluZWQgPC0gCiAgbGVmdF9qb2luKGxtX3RpZHksIGxtX3N1bW1hcnksIGJ5ID0gInZpcnVzIikKCgpgYGAKCiMjIyMgTWFrZSBwbG90CmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQoKZ2dwbG90KCkgKwogIGdlb21fcG9pbnQoZGF0YSA9IGRlcHRoc19yZWFkc19zdWIsCiAgICAgICAgICAgICBtYXBwaW5nID0gYWVzKFZpcmFsLmxvYWQsIG1lYW5fZGVwdGgsIGNvbG9yID0gdmlydXMpKSArCiAgZ2VvbV9hYmxpbmUoZGF0YSA9IGxtX2NvbWJpbmVkLCBhZXMoaW50ZXJjZXB0ID0gYChJbnRlcmNlcHQpYCwgc2xvcGUgPSBsb2dfdmlyYWxfbG9hZCksIGxpbmV0eXBlPSJkb3R0ZWQiKSArCiAgZ2VvbV90ZXh0KGRhdGEgPSBsbV9jb21iaW5lZCwKICAgICAgICAgICAgY29sb3VyID0gImJsYWNrIiwKICAgICAgICAgICAgYWVzKAogICAgICAgICAgICAgIHggPSA2KjEwMDAwLAogICAgICAgICAgICAgIHkgPSAyLAogICAgICAgICAgICAgIGxhYmVsID0gcm91bmQoQ29lZmZfeDEsIGRpZ2l0cyA9IDIpKSwKICAgICAgICAgICAgc2l6ZSA9IDMuNSkgKwogIGdlb21fdGV4dChkYXRhID0gbG1fY29tYmluZWQsCiAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsCiAgICAgICAgICAgIGFlcyh4ID0gMS41KjEwMDAwLCAKICAgICAgICAgICAgICAgIHkgPSAyLCAKICAgICAgICAgICAgICAgIGxhYmVsID0gIlNsb3BlID0iKSwKICAgICAgICAgICAgc2l6ZSA9IDMuNSkgKwogIGdlb21fdGV4dChkYXRhID0gbG1fY29tYmluZWQsCiAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsCiAgICAgICAgICAgIGFlcygKICAgICAgICAgICAgICB4ID0gNioxMDAwMCwKICAgICAgICAgICAgICB5ID0gNiwKICAgICAgICAgICAgICBsYWJlbCA9IHJvdW5kKFIyLCBkaWdpdHMgPSAyKSksCiAgICAgICAgICAgIHNpemUgPSAzLjUpICsKICBnZW9tX3RleHQoZGF0YSA9IGxtX2NvbWJpbmVkLAogICAgICAgICAgICBjb2xvdXIgPSAiYmxhY2siLAogICAgICAgICAgICBhZXMoeCA9IDIqMTAwMDAsIAogICAgICAgICAgICAgICAgeSA9IDYsIAogICAgICAgICAgICAgICAgbGFiZWwgPSAiUjIgPSIpLAogICAgICAgICAgICBzaXplID0gMy41KSArCiAgZmFjZXRfd3JhcCggfiB2aXJ1cywgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkKICApICsKICAgIHhsYWIoIkdlbm9tZSBjb3BpZXMiKSArIAogIHlsYWIoIk1lYW4gUmVhZCBEZXB0aCIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29scykgKwogIGd1aWRlcyhjb2xvciA9IEZBTFNFKSArCiAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6OmxhYmVsX21hdGgoKSkpICsgCiAgICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkKCmBgYAoKIyMjIyBGaW5hbCBwbG90CmBgYHtyfQojZ2dzYXZlKCJmaWd1cmVzL2NvbXBhcmVfc3Bpa2VfaW5zX2F0Y2MvbW9kZWxfcmVhZGRlcHRoX2RlZHVwLnBuZyIpCgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlXzEucGRmIiwKICAgICAgIHdpZHRoID0gOCwKICAgICAgIGhlaWdodCA9IDUpCgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QTkcvRmlndXJlXzEucG5nIiwKICAgICAgIHdpZHRoID0gOCwKICAgICAgIGhlaWdodCA9IDUpCgpgYGAKCgojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyMgRmlndXJlIFMxCgojIyMgUmVhZC1pbiBkYXRhIC8gTWFrZSBwbG90cwpgYGB7cn0KI21ldGFkYXRhCgptZXRhZGF0YSA8LQogIHJlYWQuY3N2KAogICAgIm1ldGFkYXRhL3NhbXBsZUlEc19URVNwaWtlSW4uY3N2IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgptZXRhZGF0YTIgPC0gbWV0YWRhdGEgfD4KICBzZWxlY3QoU2FtcGxlLklELCBOdW1iZXIub2YucmVhZC5wYWlycy4ucXVhbGl0eS5hZGFwdG9yLnRyaW1tZWQuKSB8PgogIHJlbmFtZShTYW1wbGVfaWQgPSBTYW1wbGUuSUQpIHw+CiAgcmVuYW1lKFFDX3JlYWRzID0gTnVtYmVyLm9mLnJlYWQucGFpcnMuLnF1YWxpdHkuYWRhcHRvci50cmltbWVkLikKCiNpbXBvcnQgYW5kIGNvbWJpbmUgcmVhZCBjb3VudCBmaWxlcwojZGVkdXBsaWNhdGVkIGFuZCBub24tZGVkdXBsaWNhdGVkCgpjb3VudHNfZGVkdXBfYnQgPC0KICByZWFkLnRhYmxlKAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRjb3VudF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX2RlZHVwX2F0Y2NfcmVmLnRzdiIsCiAgICBzZXAgPSAiXHQiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmNvdW50c19ub2RlZHVwX2J0IDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkY291bnRfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9ub2RlZHVwX2F0Y2NfcmVmLnRzdiIsCiAgICBzZXAgPSAiXHQiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmNvdW50c19idF9hbGwgPC0gcmJpbmQoY291bnRzX2RlZHVwX2J0LCBjb3VudHNfbm9kZWR1cF9idCkKCmNvdW50c19yZWFkcyA8LSBsZWZ0X2pvaW4oY291bnRzX2J0X2FsbCwgbWV0YWRhdGEyLCBieSA9ICJTYW1wbGVfaWQiKQoKI25vcm1hbGlzZSBieSBib3RoIHJhdyByZWFkIGNvdW50IGFuZCBnZW5vbWUgbGVuZ3RoIC0gc2hvdWxkIGJlIHRoZSBzYW1lIGFzIG1lYW4gcmVhZCBkZXB0aAoKY291bnRzX3JlYWRzX25vcm0gPC0gY291bnRzX3JlYWRzIHw+CiAgbXV0YXRlKG5vcm1fY291bnRzMSA9IG1hdGNoZWQgLyBRQ19yZWFkcykgfD4KICBtdXRhdGUobm9ybV9jb3VudHMyID0gbWF0Y2hlZCAvIFFDX3JlYWRzIC8gbGVuZ3RoKSB8PgogIG11dGF0ZShub3JtX2NvdW50czMgPSBtYXRjaGVkIC8gbGVuZ3RoKSB8PgogIG11dGF0ZShnZW5vbWVfc3RydWN0dXJlID0gY2FzZV93aGVuKCgKICAgIHZpcnVzID09ICJIdW1hbl9hZGVub3ZpcnVzXzQwIiB8CiAgICAgIHZpcnVzID09ICJIdW1hbl9iZXRhaGVycGVzdmlydXMiCiAgKSB+ICJETkEiLAogIC5kZWZhdWx0ID0gIlJOQSIKICApKQoKIyMjI2NvbXBhcmUgbGlicmFyeSBjYXB0dXJlIHBvb2wjIyMjCgpjb2xzMyA8LSBjKCIjMjI4ODMzIiwgIiNBQTMzNzciKQoKZmFjZXRfbmFtZXMgPC0gYygiZGVkdXBfVEUiID0gIkRlZHVwbGljYXRlZCIsCiAgICAgICAgICAgICAgICAgIm5vZGVkdXBfVEUiID0gIk5vbi1EZWR1cGxpY2F0ZWQiKQoKbWV0YWRhdGEzIDwtIAogIG1ldGFkYXRhIHw+CiAgc2VsZWN0KFNhbXBsZS5JRCwgUG9vbC5mb3Iuc2VxdWVuY2luZykgfD4KICByZW5hbWUoU2FtcGxlX2lkID0gU2FtcGxlLklEKSB8PgogIHJlbmFtZShQb29sID0gUG9vbC5mb3Iuc2VxdWVuY2luZykKCmNvdW50c19wb29sIDwtIGxlZnRfam9pbihjb3VudHNfcmVhZHNfbm9ybSwgbWV0YWRhdGEzLCBieSA9ICJTYW1wbGVfaWQiKQoKYGBgCgojIyMgTWFrZSBwbG90cwpgYGB7cn0KCnBvb2xfY291bnRzX3N1bSA8LSAKICBjb3VudHNfcG9vbCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gYXMuY2hhcmFjdGVyKFZpcmFsLmxvYWQpLAogICAgeSA9IGxvZzEwKG1hdGNoZWQpLAogICAgY29sb3VyID0gUG9vbAogICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgICMgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICB5bGFiKCJMb2cgKFZpcmFsIFJlYWRzKSIpICsgeGxhYigiR2Vub21lIGNvcGllcyIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sczMsIGxhYmVscyA9IGMoIlBvb2wgMSIsICJQb29sIDIiKSkgKyAKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGMoYnF1b3RlKDEwXnsyfSksIGJxdW90ZSgxMF57M30pLCBicXVvdGUoMTBeezV9KSkpCiAgCgojIHBvb2xfcmVhZGNvdW50c19ub3JtIDwtIAojICAgY291bnRzX3Bvb2wgfD4KIyAgIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiMgICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiMgICBnZ3Bsb3QoYWVzKHggPSB2aXJ1cywgeSA9IGxvZzEwKG5vcm1fY291bnRzMSkpKSArCiMgICBnZW9tX2JveHBsb3QoKSArCiMgICBmYWNldF9ncmlkKFBvb2wgfiB0eXBlKSArCiMgICB0aGVtZV9mZXcoKSArCiMgICB0aGVtZSgKIyAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAojICAgICAjIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLAojICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKIyAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKIyAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQojICAgKSArCiMgICB5bGFiKCJsb2cxMCh2aXJhbCByZWFkcy9jbGVhbmVkIHJlYWRzKSIpCgpwb29sX25vcm0xX3N1bSA8LSAKICBjb3VudHNfcG9vbCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gYXMuY2hhcmFjdGVyKFZpcmFsLmxvYWQpLAogICAgeSA9IGxvZzEwKG5vcm1fY291bnRzMSksCiAgICBjb2xvdXIgPSBQb29sCiAgKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBmYWNldF9ncmlkKCB+IHR5cGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXMpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgIyBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAjIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKSAKICApICsKICB5bGFiKCJMb2cgKHZpcmFsIHJlYWRzL2NsZWFuZWQgcmVhZHMpIikgKyB4bGFiKCJHZW5vbWUgY29waWVzIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMywgbGFiZWxzID0gYygiUG9vbCAxIiwgIlBvb2wgMiIpKSArIAogICAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBjKGJxdW90ZSgxMF57Mn0pLCBicXVvdGUoMTBeezN9KSwgYnF1b3RlKDEwXns1fSkpKQoKIyBwb29sX3JlYWRjb3VudHNfbm9ybTIgPC0gCiMgICBjb3VudHNfcG9vbCB8PgojICAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KIyAgIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KIyAgIGdncGxvdChhZXMoeCA9IHZpcnVzLCB5ID0gbG9nMTAobm9ybV9jb3VudHMyKSkpICsKIyAgIGdlb21fYm94cGxvdCgpICsKIyAgIGZhY2V0X2dyaWQoUG9vbCB+IHR5cGUpICsKIyAgIHRoZW1lX2ZldygpICsKIyAgIHRoZW1lKAojICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiMgICAgICMgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksCiMgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAojICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAojICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiMgICApICsKIyAgIHlsYWIoImxvZzEwKHZpcmFsIHJlYWRzL2NsZWFuZWQgcmVhZHMvZ2Vub21lIGxlbmd0aCkiKQoKCnBvb2xfbm9ybTJfc3VtIDwtIAogIGNvdW50c19wb29sIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBhcy5jaGFyYWN0ZXIoVmlyYWwubG9hZCksCiAgICB5ID0gbm9ybV9jb3VudHMyLAogICAgY29sb3VyID0gUG9vbAogICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgICMgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICB5bGFiKCJMb2cgKHZpcmFsIHJlYWRzL2NsZWFuZWQgcmVhZHMvZ2Vub21lIGxlbmd0aCkiKSArIHhsYWIoIkdlbm9tZSBjb3BpZXMiKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbHMzLCBsYWJlbHMgPSBjKCJQb29sIDEiLCAiUG9vbCAyIikpICsgCiAgICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGMoYnF1b3RlKDEwXnsyfSksIGJxdW90ZSgxMF57M30pLCBicXVvdGUoMTBeezV9KSkpCgoKI2ltcG9ydCBhbmQgY29tYmluZSByZWFkIGRlcHRoIGZpbGVzCgpkZXB0aF9kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKZGVwdGhfbm9kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfbm9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpkZXB0aHNfYnRfYWxsIDwtIHJiaW5kKGRlcHRoX2RlZHVwX2J0LCBkZXB0aF9ub2RlZHVwX2J0KQoKZGVwdGhzX3JlYWRzIDwtIAogIGxlZnRfam9pbihkZXB0aHNfYnRfYWxsLCBtZXRhZGF0YTIsIGJ5ID0gIlNhbXBsZV9pZCIpIHw+CiAgbXV0YXRlKGdlbm9tZV9zdHJ1Y3R1cmUgPSBjYXNlX3doZW4oKAogICAgdmlydXMgPT0gIkh1bWFuX2FkZW5vdmlydXNfNDAiIHwKICAgICAgdmlydXMgPT0gIkh1bWFuX2JldGFoZXJwZXN2aXJ1cyIKICApIH4gIkROQSIsCiAgLmRlZmF1bHQgPSAiUk5BIgogICkpCgpkZXB0aHNfcG9vbCA8LSBsZWZ0X2pvaW4oZGVwdGhzX3JlYWRzLCBtZXRhZGF0YTMsIGJ5ID0gIlNhbXBsZV9pZCIpCgojIHBvb2xfcmVhZGRlcHRocyA8LSAKIyAgIGRlcHRoc19wb29sIHw+CiMgICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgojICAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgojICAgZ2dwbG90KGFlcyh4ID0gdmlydXMsIHkgPSBsb2cxMChtZWFuX2RlcHRoKSkpICsKIyAgIGdlb21fYm94cGxvdCgpICsKIyAgIGZhY2V0X2dyaWQoUG9vbCB+IHR5cGUpICsKIyAgIHRoZW1lX2ZldygpICsKIyAgIHRoZW1lKAojICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiMgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksCiMgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAojICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAojICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiMgICApICsKIyAgIHlsYWIoIkxvZyAobWVhbiByZWFkIGRlcHRoKSIpCgpwb29sX2RlcHRoc19zdW0gPC0KICBkZXB0aHNfcG9vbCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gYXMuY2hhcmFjdGVyKFZpcmFsLmxvYWQpLAogICAgeSA9IGxvZzEwKG1lYW5fZGVwdGgpLAogICAgY29sb3VyID0gUG9vbAogICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgICMgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICB5bGFiKCJMb2cgKG1lYW4gcmVhZCBkZXB0aCkiKSArCiAgeGxhYigiR2Vub21lIGNvcGllcyIpICsgCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBjKGJxdW90ZSgxMF57Mn0pLCBicXVvdGUoMTBeezN9KSwgYnF1b3RlKDEwXns1fSkpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbHMzLCBsYWJlbHMgPSBjKCJQb29sIDEiLCAiUG9vbCAyIikpCgoKYGBgCgojIyMgKioqRmluYWwgcGxvdCoqKgpgYGB7cn0KZ2dhcnJhbmdlKAogIHBvb2xfY291bnRzX3N1bSwKICBwb29sX2RlcHRoc19zdW0sCiAgbnJvdyA9IDEsCiAgbmNvbCA9IDIsCiAgY29tbW9uLmxlZ2VuZCA9IFRSVUUsIAogIGFsaWduID0gImh2IgopCgoKI2dnc2F2ZSgiZmlndXJlcy9jb21wYXJlX3NwaWtlX2luc19hdGNjL3Bvb2xfY29tcGFyZV92aXJ1c2VzX3N1bS5wbmciLHdpZHRoPTEwLGhlaWdodD03KQoKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUERGL0ZpZ3VyZV9TMS5wZGYiLAogICAgICAgd2lkdGggPSAxMiwKICAgICAgIGhlaWdodCA9IDQpCgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QTkcvRmlndXJlX1MxLnBuZyIsCiAgICAgICB3aWR0aCA9IDEyLAogICAgICAgaGVpZ2h0ID0gNCkKCmBgYAoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCgoKIyMgRmlndXJlIFMyCgojIyMgUmVhZCBjb3VudHMKYGBge3J9CiMjIyBSZWFkLWluIGRhdGEKCiNBVENDIGdlbm9tZXMgdXBkYXRlZCB2ZXJzaW9uCiNPY3RvYmVyIDIwMjQKCiN2aXJhbCBsb2FkIHZzIHJlYWQgY291bnQgbm9ybWFsaXNlZCB1c2luZyBkaWZmZXJlbnQgbWV0aG9kcywgY29tcGFyaW5nIGRlZHVwbGljYXRlZCBhbmQgbm9uLWRlZHVwbGljYXRlZAojdXNlIGJvd3RpZTIgZGF0YQoKIyMjI3JlYWQgY291bnRzL25vcm1hbGlzZWQgcmVhZCBjb3VudHMjIyMjCgojbWV0YWRhdGEKCm1ldGFkYXRhIDwtIHJlYWQuY3N2KCJtZXRhZGF0YS9zYW1wbGVJRHNfVEVTcGlrZUluLmNzdiIsIGhlYWRlciA9IFRSVUUpCgptZXRhZGF0YTIgPC0gbWV0YWRhdGEgfD4KICBzZWxlY3QoU2FtcGxlLklELCBOdW1iZXIub2YucmVhZC5wYWlycy4ucXVhbGl0eS5hZGFwdG9yLnRyaW1tZWQuKSB8PgogIHJlbmFtZShTYW1wbGVfaWQgPSBTYW1wbGUuSUQpIHw+CiAgcmVuYW1lKFFDX3JlYWRzID0gTnVtYmVyLm9mLnJlYWQucGFpcnMuLnF1YWxpdHkuYWRhcHRvci50cmltbWVkLikKCiNpbXBvcnQgYW5kIGNvbWJpbmUgcmVhZCBjb3VudCBmaWxlcwojZGVkdXBsaWNhdGVkIGFuZCBub24tZGVkdXBsaWNhdGVkCgpjb3VudHNfZGVkdXBfYnQgPC0KICByZWFkLnRhYmxlKAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRjb3VudF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX2RlZHVwX2F0Y2NfcmVmLnRzdiIsCiAgICBzZXAgPSAiXHQiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmNvdW50c19ub2RlZHVwX2J0IDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkY291bnRfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9ub2RlZHVwX2F0Y2NfcmVmLnRzdiIsCiAgICBzZXAgPSAiXHQiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmNvdW50c19idF9hbGwgPC0gcmJpbmQoY291bnRzX2RlZHVwX2J0LCBjb3VudHNfbm9kZWR1cF9idCkKCmNvdW50c19yZWFkcyA8LSBsZWZ0X2pvaW4oY291bnRzX2J0X2FsbCwgbWV0YWRhdGEyLCBieSA9ICJTYW1wbGVfaWQiKQoKI25vcm1hbGlzZSBieSBib3RoIHJhdyByZWFkIGNvdW50IGFuZCBnZW5vbWUgbGVuZ3RoIC0gc2hvdWxkIGJlIHRoZSBzYW1lIGFzIG1lYW4gcmVhZCBkZXB0aAoKY291bnRzX3JlYWRzX25vcm0gPC0gY291bnRzX3JlYWRzIHw+CiAgbXV0YXRlKG5vcm1fY291bnRzMSA9IG1hdGNoZWQgLyBRQ19yZWFkcykgfD4KICBtdXRhdGUobm9ybV9jb3VudHMyID0gbWF0Y2hlZCAvIFFDX3JlYWRzIC8gbGVuZ3RoKSB8PgogIG11dGF0ZShub3JtX2NvdW50czMgPSBtYXRjaGVkIC8gbGVuZ3RoKSB8PgogIG11dGF0ZShnZW5vbWVfc3RydWN0dXJlID0gY2FzZV93aGVuKCgKICAgIHZpcnVzID09ICJIdW1hbl9hZGVub3ZpcnVzXzQwIiB8CiAgICAgIHZpcnVzID09ICJIdW1hbl9iZXRhaGVycGVzdmlydXMiCiAgKSB+ICJETkEiLAogIC5kZWZhdWx0ID0gIlJOQSIKICApKQoKYGBgCgoKIyMjIFJlYWQgZGVwdGhzCmBgYHtyfQojIyMjcmVhZCBkZXB0aHMjIyMjCgojaW1wb3J0IGFuZCBjb21iaW5lIHJlYWQgZGVwdGggZmlsZXMKCmRlcHRoX2RlZHVwX2J0IDwtCiAgcmVhZF90c3YoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfZGVkdXBfYXRjY19yZWYudHN2IgogICkKCmRlcHRoX25vZGVkdXBfYnQgPC0KICByZWFkX3RzdigKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9ub2RlZHVwX2F0Y2NfcmVmLnRzdiIKICApCgpkZXB0aHNfYnRfYWxsIDwtIHJiaW5kKGRlcHRoX2RlZHVwX2J0LCBkZXB0aF9ub2RlZHVwX2J0KQoKZGVwdGhzX3JlYWRzIDwtIAogIGRlcHRoc19idF9hbGwgfD4KICBsZWZ0X2pvaW4obWV0YWRhdGEyLCBieSA9ICJTYW1wbGVfaWQiKSB8PgogIG11dGF0ZShnZW5vbWVfc3RydWN0dXJlID0gY2FzZV93aGVuKCgKICAgIHZpcnVzID09ICJIdW1hbl9hZGVub3ZpcnVzXzQwIiB8CiAgICAgIHZpcnVzID09ICJIdW1hbl9iZXRhaGVycGVzdmlydXMiCiAgKSB+ICJETkEiLAogIC5kZWZhdWx0ID0gIlJOQSIKICApKSB8PgogIHJlbmFtZShWaXJhbC5sb2FkID0gYFZpcmFsIGxvYWRgKQoKYGBgCgoKIyMjIEZvcm1hdCBkYXRhCmBgYHtyfQojY2hhbmdlIGxhYmVscyBpbiBmYWNldCBwbG90cwoKZmFjZXRfbmFtZXMgPC0gYygiZGVkdXBfVEUiID0gIkRlZHVwbGljYXRlZCIsCiAgICAgICAgICAgICAgICAgIm5vZGVkdXBfVEUiID0gIk5vbi1EZWR1cGxpY2F0ZWQiKQoKY29scyA8LSBjKCIjNDQ3N0FBIiwKICAgICAgICAgICIjNjZDQ0VFIiwKICAgICAgICAgICIjMjI4ODMzIiwKICAgICAgICAgICIjQ0NCQjQ0IiwKICAgICAgICAgICIjRUU2Njc3IiwKICAgICAgICAgICIjQUEzMzc3IikKYGBgCgojIyMgTWFrZSBwbG90cwpgYGB7cn0KCiNwbG90IHZpcmFsIHJlYWQgY291bnRzIChub24gbm9ybWFsaXNlZCkKCnJlYWRfY291bnQgPC0gCiAgY291bnRzX3JlYWRzX25vcm0gfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IFZpcmFsLmxvYWQsCiAgICB5ID0gbG9nMTAobWF0Y2hlZCksCiAgICBjb2xvdXIgPSB2aXJ1cwogICkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IHZpcnVzLCBsaW5ldHlwZSA9IGdlbm9tZV9zdHJ1Y3R1cmUpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgIHZhbHVlcyA9IGNvbHMsCiAgICBsYWJlbHMgPSBjKAogICAgICAiSHVtYW4gYWRlbm92aXJ1cyA0MCIsCiAgICAgICJIdW1hbiBiZXRhaGVycGVzdmlydXMiLAogICAgICAiSHVtYW4gcmVzcGlyYXRvcnkgc3luY3l0aWFsIHZpcnVzIiwKICAgICAgIkluZmx1ZW56YSBCIHZpcnVzIiwKICAgICAgIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMiLAogICAgICAiWmlrYSB2aXJ1cyIKICAgICkKICApICsKICBzY2FsZV9saW5ldHlwZV9tYW51YWwodmFsdWVzPWMoImRvdHRlZCIsICJzb2xpZCIpKSArIAogIHlsYWIoIkxvZyAoVmlyYWwgUmVhZHMpIikgKwogIHhsYWIoIkdlbm9tZSBjb3BpZXMiKSArIAogIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKQoKcmVhZF9jb3VudF9ub3JtMSA8LSAKICBjb3VudHNfcmVhZHNfbm9ybSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gVmlyYWwubG9hZCwKICAgIHkgPSBsb2cxMChub3JtX2NvdW50czEpLAogICAgY29sb3VyID0gdmlydXMKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSB2aXJ1cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjb2xzLAogICAgbGFiZWxzID0gYygKICAgICAgIkh1bWFuIGFkZW5vdmlydXMgNDAiLAogICAgICAiSHVtYW4gYmV0YWhlcnBlc3ZpcnVzIiwKICAgICAgIkh1bWFuIHJlc3BpcmF0b3J5IHN5bmN5dGlhbCB2aXJ1cyIsCiAgICAgICJJbmZsdWVuemEgQiB2aXJ1cyIsCiAgICAgICJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIiwKICAgICAgIlppa2EgdmlydXMiCiAgICApCiAgKSArCiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcz1jKCJkb3R0ZWQiLCAic29saWQiKSkgKyAKICB5bGFiKCJMb2cgKHZpcmFsIHJlYWRzL2NsZWFuZWQgcmVhZHMpIikgKwogIHhsYWIoIkdlbm9tZSBjb3BpZXMiKSArIAogIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKQoKI25vcm1hbGlzZSBieSByYXcgcmVhZCBjb3VudCBhbmQgZ2Vub21lIGxlbmd0aAoKcmVhZF9jb3VudF9ub3JtMiA8LSAKICBjb3VudHNfcmVhZHNfbm9ybSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gKFZpcmFsLmxvYWQpLAogICAgeSA9IGxvZzEwKG5vcm1fY291bnRzMiksCiAgICBjb2xvdXIgPSB2aXJ1cwogICkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IHZpcnVzLCBsaW5ldHlwZSA9IGdlbm9tZV9zdHJ1Y3R1cmUpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgIHZhbHVlcyA9IGNvbHMsCiAgICBsYWJlbHMgPSBjKAogICAgICAiSHVtYW4gYWRlbm92aXJ1cyA0MCIsCiAgICAgICJIdW1hbiBiZXRhaGVycGVzdmlydXMiLAogICAgICAiSHVtYW4gcmVzcGlyYXRvcnkgc3luY3l0aWFsIHZpcnVzIiwKICAgICAgIkluZmx1ZW56YSBCIHZpcnVzIiwKICAgICAgIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMiLAogICAgICAiWmlrYSB2aXJ1cyIKICAgICkKICApICsKICBzY2FsZV9saW5ldHlwZV9tYW51YWwodmFsdWVzPWMoImRvdHRlZCIsICJzb2xpZCIpKSArIAogIHlsYWIoIkxvZyAodmlyYWwgcmVhZHMvY2xlYW5lZCByZWFkcy9nZW5vbWUgbGVuZ3RoKSIpICsKICB4bGFiKCJHZW5vbWUgY29waWVzIikgKyAKICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkKCgpyZWFkX2RlcHRocyA8LSAKICBkZXB0aHNfcmVhZHMgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IFZpcmFsLmxvYWQsCiAgICB5ID0gbG9nMTAobWVhbl9kZXB0aCksCiAgICBjb2xvdXIgPSB2aXJ1cwogICkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IHZpcnVzLCBsaW5ldHlwZSA9IGdlbm9tZV9zdHJ1Y3R1cmUpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgIHZhbHVlcyA9IGNvbHMsCiAgICBsYWJlbHMgPSBjKAogICAgICAiSHVtYW4gYWRlbm92aXJ1cyA0MCIsCiAgICAgICJIdW1hbiBiZXRhaGVycGVzdmlydXMiLAogICAgICAiSHVtYW4gcmVzcGlyYXRvcnkgc3luY3l0aWFsIHZpcnVzIiwKICAgICAgIkluZmx1ZW56YSBCIHZpcnVzIiwKICAgICAgIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMiLAogICAgICAiWmlrYSB2aXJ1cyIKICAgICkKICApICsKICBzY2FsZV9saW5ldHlwZV9tYW51YWwodmFsdWVzPWMoMiwgMSkpICsKICBzY2FsZV9saW5ldHlwZV9tYW51YWwodmFsdWVzPWMoImRvdHRlZCIsICJzb2xpZCIpKSArIAogIHlsYWIoIkxvZyAobWVhbiByZWFkIGRlcHRoKSIpICsKICB4bGFiKCJHZW5vbWUgY29waWVzIikgKyAKICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkKCiNnZ3NhdmUoImZpZ3VyZXMvY29tcGFyZV9zcGlrZV9pbnNfYXRjYy9tZWFuX2RlcHRoLnBkZiIsd2lkdGg9OCxoZWlnaHQ9NikKCmBgYAoKIyMjICoqKkZpbmFsIHBsb3QqKioKYGBge3IsIHdhcm5pbmcgPSBGQUxTRSwgZWNobyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9CgpnZ2FycmFuZ2UoCiAgcmVhZF9jb3VudCwKICByZWFkX2NvdW50X25vcm0xLAogIHJlYWRfY291bnRfbm9ybTIsCiAgcmVhZF9kZXB0aHMsCiAgbnJvdyA9IDIsCiAgbmNvbCA9IDIsCiAgY29tbW9uLmxlZ2VuZCA9IFRSVUUsCiAgYWxpZ24gPSAiaHYiCikKCiNnZ3NhdmUoImZpZ3VyZXMvY29tcGFyZV9zcGlrZV9pbnNfYXRjYy9sb2dfcmVhZF9jb3VudF9kZXB0aC5wbmciLHdpZHRoPTEwLGhlaWdodD03KQoKI2dnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZXNfcGRmL0ZpZ3VyZVMxLnBkZiIsd2lkdGg9MTAsaGVpZ2h0PTcpCgojYXBwYXJlbnRseSBub3JtYWxpc2VkIHJlYWQgY291bnQgdXNpbmcgbWV0aG9kIDIgc2hvdWxkIG5vdCBhY3R1YWxseSBiZSB0aGUgc2FtZQoKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUERGL0ZpZ3VyZV9TMi5wZGYiLAogICAgICAgd2lkdGggPSAxMiwKICAgICAgIGhlaWdodCA9IDgpCgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QTkcvRmlndXJlX1MyLnBuZyIsCiAgICAgICB3aWR0aCA9IDEyLAogICAgICAgaGVpZ2h0ID0gOCkKCgpgYGAKCgojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgojIyBGaWd1cmUgUzMKYGBge3J9CgojI3Bsb3RzIG9mIHJlYWQgY291bnRzIGFuZCB2aXJhbCByZWFkIGNvdW50cwojTm92ZW1iZXIgMjAyNAoKI21ldGFkYXRhCgptZXRhZGF0YSA8LQogIHJlYWQuY3N2KAogICAgIm1ldGFkYXRhL3NhbXBsZUlEc19URVNwaWtlSW4uY3N2IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgptZXRhZGF0YTIgPC0gbWV0YWRhdGEgfD4KICBzZWxlY3QoU2FtcGxlLklELCBOdW1iZXIub2YucmVhZC5wYWlycy4ucXVhbGl0eS5hZGFwdG9yLnRyaW1tZWQuKSB8PgogIHJlbmFtZShTYW1wbGVfaWQgPSBTYW1wbGUuSUQpIHw+CiAgcmVuYW1lKFFDX3JlYWRzID0gTnVtYmVyLm9mLnJlYWQucGFpcnMuLnF1YWxpdHkuYWRhcHRvci50cmltbWVkLikKCiNpbXBvcnQgcmVhZCBjb3VudCBmaWxlcwoKY291bnRzX2RlZHVwX2J0IDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkY291bnRfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpjb3VudHNfbm9kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGNvdW50X3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfbm9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgojaW1wb3J0IHZpcmFsIHJlYWRzIG1hcHBlZCAodG8gY2FsY3VsYXRlIHByb3BvcnRpb25zKQoKdmlyYWxfcmVhZHNfZGVkdXAgPC0KICByZWFkLmNzdigKICAgICJkYXRhX1RFL3RvdGFsX3ZpcnVzX21hcHBlZF9yZWFkc19wZXJfc2FtcGxlX2RlZHVwX2F0Y2NfcmVmXzIwMjQxMTA4LmNzdiIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKdmlyYWxfcmVhZHNfbm9kZWR1cCA8LQogIHJlYWQuY3N2KAogICAgImRhdGFfVEUvdG90YWxfdmlydXNfbWFwcGVkX3JlYWRzX3Blcl9zYW1wbGVfbm9kZWR1cF9hdGNjX3JlZl8yMDI0MTEwOC5jc3YiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmNvbHMyIDwtIGMoIiNCQjU1NjYiLCAiIzAwNDQ4OCIpCgpmYWNldF9uYW1lcyA8LSBjKCJkZWR1cF9URSIgPSAiRGVkdXBsaWNhdGVkIiwKICAgICAgICAgICAgICAgICAibm9kZWR1cF9URSIgPSAiTm9uLURlZHVwbGljYXRlZCIpCgpyZWFkc19tZXRhZGF0YV9kZWR1cCA8LQogIGxlZnRfam9pbihjb3VudHNfZGVkdXBfYnQsIG1ldGFkYXRhMiwgYnkgPSAiU2FtcGxlX2lkIikKCnJlYWRzX3ZpcmFsX2RlZHVwIDwtCiAgbGVmdF9qb2luKHJlYWRzX21ldGFkYXRhX2RlZHVwLCB2aXJhbF9yZWFkc19kZWR1cCwgYnkgPSAiU2FtcGxlX2lkIikKCnJlYWRzX21ldGFkYXRhX25vZGVkdXAgPC0KICBsZWZ0X2pvaW4oY291bnRzX25vZGVkdXBfYnQsIG1ldGFkYXRhMiwgYnkgPSAiU2FtcGxlX2lkIikKCnJlYWRzX3ZpcmFsX25vZGVkdXAgPC0KICBsZWZ0X2pvaW4ocmVhZHNfbWV0YWRhdGFfbm9kZWR1cCwgdmlyYWxfcmVhZHNfbm9kZWR1cCwgYnkgPSAiU2FtcGxlX2lkIikKCnJlYWRzX3ZpcmFsX2FsbCA8LSByYmluZChyZWFkc192aXJhbF9kZWR1cCwgcmVhZHNfdmlyYWxfbm9kZWR1cCkKCgpyZWFkc19wbG90IDwtIAogIHJlYWRzX3ZpcmFsX2FsbCB8PgogIGdyb3VwX2J5KEJhY2tncm91bmQsIFNhbXBsZV9pZCwgVmlyYWwubG9hZCwgdHlwZSkgfD4KICBzdW1tYXJpc2UoCiAgICB0b3RhbF9yZWFkcyA9IChRQ19yZWFkcyAqIDIpLAogICAgdmlyYWxfcmVhZHMgPSB0b3RhbF92aXJ1c19yZWFkcywKICAgIEFUQ0NfcmVhZHMgPSBzdW0obWF0Y2hlZCksCiAgICBwcm9wX0FUQ0MgPSBBVENDX3JlYWRzIC8gdG90YWxfcmVhZHMsCiAgICBwcm9wX3ZpcmFsID0gdG90YWxfdmlydXNfcmVhZHMgLyB0b3RhbF9yZWFkcywKICAgIGRpZmYgPSB2aXJhbF9yZWFkcyAtIEFUQ0NfcmVhZHMKICApIHw+CiAgdW5pcXVlKCkKCmBgYAoKIyMjIE1ha2UgcGxvdHMKYGBge3IsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9Cgp0b3RhbF9yZWFkcyA8LSAKICByZWFkc19wbG90IHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9ICh0b3RhbF9yZWFkcyksCiAgICBjb2xvdXIgPSBCYWNrZ3JvdW5kCiAgKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gQmFja2dyb3VuZCksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKCB+IHR5cGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXMpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX3lfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKSArIAogICAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6OmxhYmVsX21hdGgoKSkpICsgeGxhYigiR2Vub21lIGNvcGllcyIpICsKICAjIGdndGl0bGUoIkFsbCIpICsKICB5bGFiKCJUb3RhbCBudW1iZXIgb2YgcmVhZHMiKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbHMyLCBsYWJlbHMgPSBjKCJNMSIsICJNMiIpKQoKdmlyYWxfcmVhZHMgPC0gCiAgcmVhZHNfcGxvdCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gVmlyYWwubG9hZCwKICAgIHkgPSAodmlyYWxfcmVhZHMpLAogICAgY29sb3VyID0gQmFja2dyb3VuZAogICkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IEJhY2tncm91bmQpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkgKyAKICAgIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKSArIHhsYWIoIkdlbm9tZSBjb3BpZXMiKSArCiAgIyBnZ3RpdGxlKCJWaXJhbCByZWFkcyIpICsKICB5bGFiKCJOdW1iZXIgb2YgdmlyYWwgcmVhZHMiKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbHMyLCBsYWJlbHMgPSBjKCJNMSIsICJNMiIpKQoKQVRDQ19yZWFkcyA8LSAKICByZWFkc19wbG90IHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IChBVENDX3JlYWRzKSwKICAgIGNvbG91ciA9IEJhY2tncm91bmQKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBCYWNrZ3JvdW5kKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6OmxhYmVsX21hdGgoKSkpICsgCiAgICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkgKyB4bGFiKCJHZW5vbWUgY29waWVzIikgKwogIGdndGl0bGUoIlNwaWtlLWluIFZpcmFsIFJlYWRzIikgKwogIHlsYWIoIlNwaWtlLWluIFZpcmFsIFJlYWRzIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMiwgbGFiZWxzID0gYygiTTEiLCAiTTIiKSkKCnByb3BfQVRDQyA8LSByZWFkc19wbG90IHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcyh4ID0gVmlyYWwubG9hZCwgeSA9IHByb3BfQVRDQywgY29sb3VyID0gQmFja2dyb3VuZCkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IEJhY2tncm91bmQpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICAgIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKSArIHhsYWIoIkdlbm9tZSBjb3BpZXMiKSArCiAgZ2d0aXRsZSgiU3Bpa2UtaW4gdmlyYWwgcmVhZHMiKSArCiAgeWxhYigiUHJvcG9ydGlvbiIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sczIsIGxhYmVscyA9IGMoIk0xIiwgIk0yIikpCgpwcm9wX3ZpcmFsIDwtIHJlYWRzX3Bsb3QgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKHggPSBWaXJhbC5sb2FkLCB5ID0gcHJvcF92aXJhbCwgY29sb3VyID0gQmFja2dyb3VuZCkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IEJhY2tncm91bmQpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKSArIHhsYWIoIkdlbm9tZSBjb3BpZXMiKSArCiAgIyBnZ3RpdGxlKCJWaXJhbCByZWFkcyIpICsKICB5bGFiKCJQcm9wb3J0aW9uIG9mIHZpcmFsIHJlYWRzIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMiwgbGFiZWxzID0gYygiTTEiLCAiTTIiKSkgKyBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPWMoMCwxLjApKQoKCiNnZ2FycmFuZ2UodG90YWxfcmVhZHMsdmlyYWxfcmVhZHMsQVRDQ19yZWFkcyxwcm9wX3ZpcmFsLHByb3BfQVRDQyxucm93PTIsbmNvbD0zLGNvbW1vbi5sZWdlbmQgPSBUUlVFKQoKYGBgCgojIyMgKioqRmluYWwgcGxvdCoqKgpgYGB7ciwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KCmdnYXJyYW5nZSh0b3RhbF9yZWFkcywKICAgICAgICAgIHZpcmFsX3JlYWRzLAogICAgICAgICAgcHJvcF92aXJhbCwKICAgICAgICAgIG5yb3cgPSAzLAogICAgICAgICAgY29tbW9uLmxlZ2VuZCA9IFRSVUUsCiAgICAgICAgICBhbGlnbiA9ICJodiIpCgojZ2dzYXZlKCJmaWd1cmVzL2NvbXBhcmVfc3Bpa2VfaW5zX2F0Y2MvYmFja2dyb3VuZHNfcmVhZHMucG5nIikKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BERi9GaWd1cmVfUzMucGRmIiwgCiAgICAgICB3aWR0aCA9IDgsCiAgICAgICBoZWlnaHQgPSA4KQoKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUE5HL0ZpZ3VyZV9TMy5wbmciLCAKICAgICAgIHdpZHRoID0gOCwKICAgICAgIGhlaWdodCA9IDgpCgojIyMjY29tcGFyZSBwcm9wb3J0aW9uIHZpcmFsIHJlYWRzIHBlciBwb29sIHdpdGggc2hvdGd1biMjIyMKCiMgbWV0YWRhdGEzIDwtIG1ldGFkYXRhIHw+CiMgICBzZWxlY3QoU2FtcGxlLklELAojICAgICAgICAgIE51bWJlci5vZi5yZWFkLnBhaXJzLi5xdWFsaXR5LmFkYXB0b3IudHJpbW1lZC4sCiMgICAgICAgICAgUG9vbC5mb3Iuc2VxdWVuY2luZykgfD4KIyAgIHJlbmFtZShTYW1wbGVfaWQgPSBTYW1wbGUuSUQpIHw+CiMgICByZW5hbWUoUUNfcmVhZHMgPSBOdW1iZXIub2YucmVhZC5wYWlycy4ucXVhbGl0eS5hZGFwdG9yLnRyaW1tZWQuKQojIAojIHJlYWRzX3ZpcmFsX2RlZHVwMyA8LQojICAgZnVsbF9qb2luKG1ldGFkYXRhMywgdmlyYWxfcmVhZHNfZGVkdXAsIGJ5ID0gIlNhbXBsZV9pZCIpCiMgCiMgcmVhZHNfdmlyYWxfbm9kZWR1cDMgPC0KIyAgIGZ1bGxfam9pbihtZXRhZGF0YTMsIHZpcmFsX3JlYWRzX25vZGVkdXAsIGJ5ID0gIlNhbXBsZV9pZCIpCiMgCiMgcmVhZHNfdmlyYWxfZGVkdXAzIHw+CiMgICBncm91cF9ieShQb29sLmZvci5zZXF1ZW5jaW5nKSB8PgojICAgc3VtbWFyaXNlKAojICAgICB2aXJhbF9yZWFkcyA9IHN1bSh0b3RhbF92aXJ1c19yZWFkcyksCiMgICAgIHRvdGFsX3JlYWRzID0gc3VtKFFDX3JlYWRzICogMiksCiMgICAgIHByb3BfdmlyYWwgPSB2aXJhbF9yZWFkcyAvIHRvdGFsX3JlYWRzCiMgICApCiMgCiMgcG9seW9taWNzIDwtCiMgICByZWFkLmNzdigKIyAgICAgImRhdGFfcG9seW9taWNzL3RvdGFsX3ZpcnVzX21hcHBlZF9yZWFkc19wZXJfc2FtcGxlX2RlZHVwLmNzdiIKIyAgICkKIyAKIyAjcmVhZCBkYXRhIGZyb20gcG9seW9taWNzX2luZGV4ZXNfc3RlZmFubyBkb2N1bWVudAojIHRvdGFsX3JlYWRzIDwtIGRhdGEuZnJhbWUodG90YWxfcmVhZHMgPSBjKDU5NDI3NjAsIDc3MTQyNzUpKQojIAojIGtlZXBzIDwtIGMoIlJOQS1Nc3AtcDIiLCAiUk5BLU1zcC1wOCIpCiMgCiMgcG9seW9taWNzX3JlYWRfcHJvcCA8LSBwb2x5b21pY3MgfD4KIyAgIGZpbHRlcihTYW1wbGVfaWQgJWluJSBrZWVwcykKIyAKIyBwb2x5b21pY3NfcmVhZF9wcm9wMiA8LSBjYmluZChwb2x5b21pY3NfcmVhZF9wcm9wLCB0b3RhbF9yZWFkcykKIyAKIyBwb2x5b21pY3NfcmVhZF9wcm9wMiB8PgojICAgc3VtbWFyaXNlKHByb3BfdmlyYWwgPSB0b3RhbF92aXJ1c19yZWFkcyAvIHRvdGFsX3JlYWRzKQoKYGBgCgojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIE5vIGxvbmdlciByZXF1aXJlZD8gRmlndXJlIFM0CgojIyMgTWFrZSBwbG90cwpgYGB7cn0KIyMjI3JlYWQgY291bnRzL2RlcHRocyBzcGxpdCBieSBiYWNrZ3JvdW5kIyMjIwoKI2NoYW5nZSBsYWJlbHMgaW4gZmFjZXQgcGxvdHMKCmZhY2V0X25hbWVzX2JnIDwtIGMoCiAgImRlZHVwX1RFIiA9ICJEZWR1cGxpY2F0ZWQiLAogICJub2RlZHVwX1RFIiA9ICJOb24tRGVkdXBsaWNhdGVkIiwKICAicDIiID0gIk0xIiwKICAicDgiID0gIk0yIgopCgojYnJlYWsgZG93biBieSBCYWNrZ3JvdW5kIHggdmlydXMKCmJhY2tncm91bmRfY291bnRzX3JlYWRzIDwtIAogIGNvdW50c19yZWFkc19ub3JtIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IGxvZzEwKG1hdGNoZWQpLAogICAgY29sb3VyID0gdmlydXMKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSB2aXJ1cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoQmFja2dyb3VuZCB+IHR5cGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXNfYmcpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgIHZhbHVlcyA9IGNvbHMsCiAgICBsYWJlbHMgPQogICAgICBjKAogICAgICAiSHVtYW4gYWRlbm92aXJ1cyA0MCIsCiAgICAgICJIdW1hbiBiZXRhaGVycGVzdmlydXMiLAogICAgICAiSHVtYW4gcmVzcGlyYXRvcnkgc3luY3l0aWFsIHZpcnVzIiwKICAgICAgIkluZmx1ZW56YSBCIHZpcnVzIiwKICAgICAgIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMiLAogICAgICAiWmlrYSB2aXJ1cyIKICAgICAgKQogICkgKwogIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9sb2cxMCgpKSArCiAgeWxhYigiTG9nIChWaXJhbCBSZWFkcykiKQoKYmFja2dyb3VuZHNfY291bnRzX3JlYWRzX25vcm0gPC0gCiAgY291bnRzX3JlYWRzX25vcm0gfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IFZpcmFsLmxvYWQsCiAgICB5ID0gbG9nMTAobm9ybV9jb3VudHMxKSwKICAgIGNvbG91ciA9IHZpcnVzCiAgKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gdmlydXMsIGxpbmV0eXBlID0gZ2Vub21lX3N0cnVjdHVyZSksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKEJhY2tncm91bmQgfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzX2JnKSkgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjb2xzLAogICAgbGFiZWxzID0gYygKICAgICAgIkh1bWFuIGFkZW5vdmlydXMgNDAiLAogICAgICAiSHVtYW4gYmV0YWhlcnBlc3ZpcnVzIiwKICAgICAgIkh1bWFuIHJlc3BpcmF0b3J5IHN5bmN5dGlhbCB2aXJ1cyIsCiAgICAgICJJbmZsdWVuemEgQiB2aXJ1cyIsCiAgICAgICJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIiwKICAgICAgIlppa2EgdmlydXMiCiAgICApCiAgKSArCiAgc2NhbGVfeF9sb2cxMChsYWJlbCA9IHNjYWxlczo6bGFiZWxfbG9nMTAoKSkgKwogIHlsYWIoIkxvZyAodmlyYWwgcmVhZHMvY2xlYW5lZCByZWFkcykiKQoKYmFja2dyb3VuZHNfY291bnRzX3JlYWRzX25vcm0yIDwtIAogIGNvdW50c19yZWFkc19ub3JtIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IGxvZzEwKG5vcm1fY291bnRzMiksCiAgICBjb2xvdXIgPSB2aXJ1cwogICkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IHZpcnVzLCBsaW5ldHlwZSA9IGdlbm9tZV9zdHJ1Y3R1cmUpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZChCYWNrZ3JvdW5kIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lc19iZykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKAogICAgdmFsdWVzID0gY29scywKICAgIGxhYmVscyA9IGMoCiAgICAgICJIdW1hbiBhZGVub3ZpcnVzIDQwIiwKICAgICAgIkh1bWFuIGJldGFoZXJwZXN2aXJ1cyIsCiAgICAgICJIdW1hbiByZXNwaXJhdG9yeSBzeW5jeXRpYWwgdmlydXMiLAogICAgICAiSW5mbHVlbnphIEIgdmlydXMiLAogICAgICAiTWFtbWFsaWFuIG9ydGhvcmVvdmlydXMgMyIsCiAgICAgICJaaWthIHZpcnVzIgogICAgKQogICkgKwogIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9sb2cxMCgpKSArCiAgeWxhYigiTG9nICh2aXJhbCByZWFkcy9jbGVhbmVkIHJlYWRzL2dlbm9tZSBsZW5ndGgpIikKCmJhY2tncm91bmRfcmVhZF9kZXB0aHMgPC0gCiAgZGVwdGhzX3JlYWRzIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IGxvZzEwKG1lYW5fZGVwdGgpLAogICAgY29sb3VyID0gdmlydXMKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSB2aXJ1cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoQmFja2dyb3VuZCB+IHR5cGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXNfYmcpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IiksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKQogICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgIHZhbHVlcyA9IGNvbHMsCiAgICBsYWJlbHMgPSBjKAogICAgICAiSHVtYW4gYWRlbm92aXJ1cyA0MCIsCiAgICAgICJIdW1hbiBiZXRhaGVycGVzdmlydXMiLAogICAgICAiSHVtYW4gcmVzcGlyYXRvcnkgc3luY3l0aWFsIHZpcnVzIiwKICAgICAgIkluZmx1ZW56YSBCIHZpcnVzIiwKICAgICAgIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMiLAogICAgICAiWmlrYSB2aXJ1cyIKICAgICkKICApICsKICBzY2FsZV94X2xvZzEwKGxhYmVsID0gc2NhbGVzOjpsYWJlbF9sb2cxMCgpKSArCiAgeWxhYigiTG9nIChtZWFuIHJlYWQgZGVwdGgpIikKCmBgYAoKIyMjICoqKkZpbmFsIHBsb3QqKiogCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTYsIGZpZy5oZWlnaHQ9OH0KCmdnYXJyYW5nZSgKICBiYWNrZ3JvdW5kX2NvdW50c19yZWFkcywKICBiYWNrZ3JvdW5kc19jb3VudHNfcmVhZHNfbm9ybSwKICBiYWNrZ3JvdW5kc19jb3VudHNfcmVhZHNfbm9ybTIsCiAgYmFja2dyb3VuZF9yZWFkX2RlcHRocywKICBucm93ID0gMiwKICBuY29sID0gMiwKICBjb21tb24ubGVnZW5kID0gVFJVRSwKICBhbGlnbiA9ICJodiIKKQoKI2dnc2F2ZSgiZmlndXJlcy9jb21wYXJlX3NwaWtlX2luc19hdGNjL2JhY2tncm91bmRzX3JlYWRfY291bnRfZGVwdGgucG5nIix3aWR0aD0xMCxoZWlnaHQ9NykKCiNnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVzX3BkZi9GaWd1cmVTNC5wZGYiLHdpZHRoPTEwLGhlaWdodD03KQoKYGBgCgoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgPj4+IEZpZ3VyZSAyOiBwbG90cyBvZiBURSBleHBlcmltZW50IGRhdGEgLSBnZW5vbWUgY292ZXJhZ2UgJiBwZXIgc2l0ZSBjb3ZlcmFnZQoKIyMjIFJlYWQtaW4gZGF0YQpgYGB7cn0KCiNwbG90cyBvZiBURSBleHBlcmltZW50IGRhdGEgLSBnZW5vbWUgY292ZXJhZ2UgJiBwZXIgc2l0ZSBjb3ZlcmFnZQojYWxzbyBzZXBhcmF0ZWQgYnkgdmlydXNlcwojQVRDQyBnZW5vbWVzIHVwZGF0ZWQgdmVyc2lvbgojT2N0b2JlciAyMDI0CgojdXNlIGJvd3RpZTIgZGF0YQoKIyMjI2dlbm9tZSBjb3ZlcmFnZSMjIyMKCnVuemlwKHppcGZpbGUgPSAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zaXRlX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9kZWR1cF9hdGNjX3JlZi50c3YuemlwIiwgZXhkaXIgPSAiZGF0YV9URS8iKQoKdW56aXAoemlwZmlsZSA9ICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NpdGVfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX25vZGVkdXBfYXRjY19yZWYudHN2LnppcCIsIGV4ZGlyID0gImRhdGFfVEUvIikKCmRlZHVwX3Blcl9zaXRlIDwtCiAgcmVhZF90c3YoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zaXRlX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9kZWR1cF9hdGNjX3JlZi50c3YiCiAgKQoKCm5vZGVkdXBfcGVyX3NpdGUgPC0KICByZWFkX3RzdigKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NpdGVfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX25vZGVkdXBfYXRjY19yZWYudHN2IgogICkKCmZpbGUucmVtb3ZlKCJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NpdGVfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX2RlZHVwX2F0Y2NfcmVmLnRzdiIpCgpmaWxlLnJlbW92ZSggImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRkZXB0aF9wZXJfc2l0ZV9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfbm9kZWR1cF9hdGNjX3JlZi50c3YiKQoKI2FkZCBsZW5ndGggY29sdW1uIGZyb20gcmVhZCBkZXB0aCBmaWxlIHRvIHBlciBzaXRlIGZpbGUKCiNtZXRhZGF0YQoKbWV0YWRhdGEgPC0KICByZWFkLmNzdigKICAgICJtZXRhZGF0YS9zYW1wbGVJRHNfVEVTcGlrZUluLmNzdiIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKbWV0YWRhdGEyIDwtIAogIG1ldGFkYXRhIHw+CiAgc2VsZWN0KFNhbXBsZS5JRCwgTnVtYmVyLm9mLnJlYWQucGFpcnMuLnF1YWxpdHkuYWRhcHRvci50cmltbWVkLikgfD4KICByZW5hbWUoU2FtcGxlX2lkID0gU2FtcGxlLklEKSB8PgogIHJlbmFtZShRQ19yZWFkcyA9IE51bWJlci5vZi5yZWFkLnBhaXJzLi5xdWFsaXR5LmFkYXB0b3IudHJpbW1lZC4pCgojaW1wb3J0IGFuZCBjb21iaW5lIHJlYWQgY291bnQgZmlsZXMKCiNkZWR1cGxpY2F0ZWQgYW5kIG5vbi1kZWR1cGxpY2F0ZWQKCmNvdW50c19kZWR1cF9idCA8LQogIHJlYWRfdHN2KAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRjb3VudF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX2RlZHVwX2F0Y2NfcmVmLnRzdiIKICApCgpjb3VudHNfbm9kZWR1cF9idCA8LQogIHJlYWRfdHN2KAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRjb3VudF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX25vZGVkdXBfYXRjY19yZWYudHN2IgogICkKCmNvdW50c19idF9hbGwgPC0gcmJpbmQoY291bnRzX2RlZHVwX2J0LCBjb3VudHNfbm9kZWR1cF9idCkKCmNvdW50c19yZWFkcyA8LSBsZWZ0X2pvaW4oY291bnRzX2J0X2FsbCwgbWV0YWRhdGEyLCBieSA9ICJTYW1wbGVfaWQiKQoKYGBgCgojIyMgRm9ybWF0IGRhdGEKYGBge3J9CiNub3JtYWxpc2UgYnkgYm90aCByYXcgcmVhZCBjb3VudCBhbmQgZ2Vub21lIGxlbmd0aCAtIHNob3VsZCBiZSB0aGUgc2FtZSBhcyBtZWFuIHJlYWQgZGVwdGgKCmNvdW50c19yZWFkc19ub3JtIDwtIAogIGNvdW50c19yZWFkcyB8PgogIG11dGF0ZShub3JtX2NvdW50czEgPSBtYXRjaGVkIC8gUUNfcmVhZHMpIHw+CiAgbXV0YXRlKG5vcm1fY291bnRzMiA9IG1hdGNoZWQgLyBRQ19yZWFkcyAvIGxlbmd0aCkgfD4KICBtdXRhdGUobm9ybV9jb3VudHMzID0gbWF0Y2hlZCAvIGxlbmd0aCkgfD4KICBtdXRhdGUoZ2Vub21lX3N0cnVjdHVyZSA9IGNhc2Vfd2hlbigoCiAgICB2aXJ1cyA9PSAiSHVtYW5fYWRlbm92aXJ1c180MCIgfAogICAgICB2aXJ1cyA9PSAiSHVtYW5fYmV0YWhlcnBlc3ZpcnVzIgogICkgfiAiRE5BIiwKICAuZGVmYXVsdCA9ICJSTkEiCiAgKSkKCmxlbmd0aHMgPC0gCiAgY291bnRzX3JlYWRzX25vcm0gfD4KICBzZWxlY3QodmlydXMsIGxlbmd0aCkgfD4KICBkaXN0aW5jdCgpCgojY2FsY3VsYXRlIGdlbm9tZSBjb3ZlcmFnZQoKcGVyc2l0ZV9jb3ZlcmFnZV9kZWR1cCA8LSAKICBkZWR1cF9wZXJfc2l0ZSB8PgogIHJlbmFtZShWaXJhbC5sb2FkID0gYFZpcmFsIGxvYWRgKSB8PgogIGdyb3VwX2J5KFNhbXBsZV9pZCwgdmlydXMsIFZpcmFsLmxvYWQsIEJhY2tncm91bmQsIHR5cGUpIHw+CiAgZmlsdGVyKGNvdmVyYWdlID4gMCkgfD4KICBzdW1tYXJpc2UoZ2Vub21lX2NvdmVyYWdlID0gbigpKSB8PgogIGxlZnRfam9pbihsZW5ndGhzKSB8PgogIG11dGF0ZShwZXJjZW50X2NvdmVyYWdlID0gZ2Vub21lX2NvdmVyYWdlIC8gbGVuZ3RoKQoKcGVyc2l0ZV9jb3ZlcmFnZV9ub2RlZHVwIDwtIAogIG5vZGVkdXBfcGVyX3NpdGUgfD4KICByZW5hbWUoVmlyYWwubG9hZCA9IGBWaXJhbCBsb2FkYCkgfD4KICBncm91cF9ieShTYW1wbGVfaWQsIHZpcnVzLCBWaXJhbC5sb2FkLCBCYWNrZ3JvdW5kLCB0eXBlKSB8PgogIGZpbHRlcihjb3ZlcmFnZSA+IDApIHw+CiAgc3VtbWFyaXNlKGdlbm9tZV9jb3ZlcmFnZSA9IG4oKSkgfD4KICBsZWZ0X2pvaW4obGVuZ3RocykgfD4KICBtdXRhdGUocGVyY2VudF9jb3ZlcmFnZSA9IGdlbm9tZV9jb3ZlcmFnZSAvIGxlbmd0aCkKCnBlcnNpdGVfY292ZXJhZ2VfYm90aCA8LQogIHJiaW5kKHBlcnNpdGVfY292ZXJhZ2VfZGVkdXAsIAogICAgICAgIHBlcnNpdGVfY292ZXJhZ2Vfbm9kZWR1cCkKCmNvdmVyYWdlX2xhYmVscyA8LSBjKCIwIiA9ICJDb250cm9sIiwKICAgICAgICAgICAgICAgICAgICAgIjEwMCIgPSAiMTBeezJ9IiwKICAgICAgICAgICAgICAgICAgICAgIjEwMDAiID0gIjEwXnszfSIsCiAgICAgICAgICAgICAgICAgICAgICIxMDAwMCIgPSAiMTBeezV9IiwKICAgICAgICAgICAgICAgICAgICAgImRlZHVwX1RFIiA9ICJEZWR1cGxpY2F0ZWQiLAogICAgICAgICAgICAgICAgICAgICAibm9kZWR1cF9URSI9ICJOb24tRGVkdXBsaWNhdGVkIikKCmNvdmVyYWdlX2xhYmVsczIgPC0gYygiMCIgPSAiQ29udHJvbCIsCiAgICAgICAgICAgICAgICAgICAgICAiMTAwIiA9ICIxMF57Mn0iLAogICAgICAgICAgICAgICAgICAgICAgIjEwMDAiID0gIjEwXnszfSIsCiAgICAgICAgICAgICAgICAgICAgICAiMTAwMDAiID0gIjEwXns1fSIpCmBgYAoKIyMjIE1ha2UgcGxvdHMKYGBge3IsIGVjaG8gPSBGQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9Nn0KCmNvbHMyIDwtIGMoIiNCQjU1NjYiLAogICAgICAgICAgICIjMDA0NDg4IikKCmNvbHM0IDwtIGMoIiNEREFBMzMiLAogICAgICAgICAgICIjQkI1NTY2IiwKICAgICAgICAgICAiIzAwNDQ4OCIpCgoKcGVyc2l0ZV9jb3ZlcmFnZV9ib3RoJFZpcmFsLmxvYWQgPC0gZmFjdG9yKHBlcnNpdGVfY292ZXJhZ2VfYm90aCRWaXJhbC5sb2FkLCBsYWJlbHMgPSBjKCIwIiwKICAgICIxMF57Mn0iLCAKICAgICIxMF57M30iLCAKICAgICIxMF57NX0iCiAgICApKQoKCiMjYXJlIHRoZSBkZWR1cGxpY2F0ZWQgYW5kIG5vbiBkZWR1cGxpY2F0ZWQgZGF0YXNldHMgaWRlbnRpY2FsPz8KIyNpZiB0aGV5IGFyZSB0aGUgc2FtZSBjYW4gbWF5YmUganVzdCBzaG93IG9uZQojc2hvdyBkZWR1cGxpY2F0ZWQKCnBlcnNpdGVfY292ZXJhZ2VfYm90aCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGZpbHRlcih0eXBlID09ICJkZWR1cF9URSIpIHw+CiAgZ2dwbG90KGFlcyh4ID0gdmlydXMsIHkgPSBwZXJjZW50X2NvdmVyYWdlLCBjb2xvdXIgPSBCYWNrZ3JvdW5kKSkgKwogIGdlb21fYm94cGxvdChvdXRsaWVyLnNoYXBlID0gTkEpICsKICBnZW9tX3BvaW50KHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAuNzUpKSArCiAgZmFjZXRfZ3JpZCh+YXMuY2hhcmFjdGVyKFZpcmFsLmxvYWQpLCBsYWJlbGxlciA9IGxhYmVsX3BhcnNlZCkgKwogIHRoZW1lX2ZldygpICsKICB5bGFiKCJHZW5vbWUgY292ZXJhZ2UiKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbHMyLCBsYWJlbHMgPSBjKCJNMSIsICJNMiIpKSArCiAgc2NhbGVfeF9kaXNjcmV0ZSgKICAgIGxhYmVscyA9IGMoCiAgICAgICJIdW1hbiBhZGVub3ZpcnVzIDQwIiwKICAgICAgIkh1bWFuIGJldGFoZXJwZXN2aXJ1cyIsCiAgICAgICJIdW1hbiByZXNwaXJhdG9yeSBzeW5jeXRpYWwgdmlydXMiLAogICAgICAiSW5mbHVlbnphIEIgdmlydXMiLAogICAgICAiTWFtbWFsaWFuIG9ydGhvcmVvdmlydXMgMyIsCiAgICAgICJaaWthIHZpcnVzIgogICAgKQogICkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDEpKQoKYGBgCgojIyMgKioqRmluYWwgcGxvdCoqKgpgYGB7ciwgZWNobyA9IEZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojZ2dzYXZlKCJmaWd1cmVzL2NvbXBhcmVfc3Bpa2VfaW5zX2F0Y2MvZ2Vub21lX2Nvdl9kZWR1cG9ubHkucG5nIix3aWR0aD0xNSxoZWlnaHQ9NikKCmdnc2F2ZSgKICAiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BERi9GaWd1cmVfMi5wZGYiLAogIHdpZHRoID0gMTUsCiAgaGVpZ2h0ID0gNgopCgpnZ3NhdmUoCiAgImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QTkcvRmlndXJlXzIucG5nIiwKICB3aWR0aCA9IDE1LAogIGhlaWdodCA9IDYKKQoKCmBgYAoKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIEZpZ3VyZSBTNApgYGB7cn0KCnBlcnNpdGVfYm90aCA8LSByYmluZChkZWR1cF9wZXJfc2l0ZSwgbm9kZWR1cF9wZXJfc2l0ZSkKCnBlcnNpdGVfcmVhZHMgPC0gbGVmdF9qb2luKHBlcnNpdGVfYm90aCwgbWV0YWRhdGEyLCBieSA9ICJTYW1wbGVfaWQiKQoKcGVyc2l0ZV9ub3JtIDwtIHBlcnNpdGVfcmVhZHMgfD4KICBtdXRhdGUobm9ybV9jb3YgPSBjb3ZlcmFnZSAvIFFDX3JlYWRzKQoKY292ZXJhZ2VfbGFiZWxzMyA8LWMoIjEwMCIgPSAiMWUrMDIiLAogICAgICAgICAgICAgICAgICAgICIxMDAwIiA9ICIxZSswMyIsCiAgICAgICAgICAgICAgICAgICAgIjEwMDAwMCIgPSAiMWUrMDUiLAogICAgICAgICAgICAgICAgICAgICJwMiIgPSAiTTEiLAogICAgICAgICAgICAgICAgICAgICJwOCI9ICJNMiIpCgpwZXJzaXRlX25vcm0kYFZpcmFsIGxvYWRgIDwtIAogIGZhY3RvcihwZXJzaXRlX25vcm0kYFZpcmFsIGxvYWRgLCAKICAgICAgICAgbGFiZWxzID0gYygiMCIsCiAgICAgICAgICAgICAgICAgICAgIjEwXnsyfSIsIAogICAgICAgICAgICAgICAgICAgICIxMF57M30iLAogICAgICAgICAgICAgICAgICAgICIxMF57NX0iKSkKCgpwZXJzaXRlX25vcm0gfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBmaWx0ZXIodHlwZSA9PSAiZGVkdXBfVEUiKSB8PgogIGZpbHRlcih2aXJ1cyA9PSAiSHVtYW5fcmVzcGlyYXRvcnlfc3luY3l0aWFsX3ZpcnVzIikgfD4KICByZW5hbWUoVmlyYWwubG9hZCA9IGBWaXJhbCBsb2FkYCkgfD4KICBnZ3Bsb3QoYWVzKHggPSBzaXRlLCB5ID0gY292ZXJhZ2UsIGZpbGwgPSBCYWNrZ3JvdW5kKSkgKwogIGdlb21fY29sKCkgKwogIGZhY2V0X3dyYXAoVmlyYWwubG9hZCB+IFNhbXBsZV9pZCwgbGFiZWwgPSBsYWJlbF9wYXJzZWQpICsKICB5bGFiKCJDb3ZlcmFnZSIpICsKICBnZ3RpdGxlKCJIdW1hbiBSU1YgKGRlZHVwbGljYXRlZCkiKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQodGl0bGUgPSAiQmFja2dyb3VuZCIpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX3lfbG9nMTAoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sczIsIGxhYmVscyA9IGMoIk0xIiwgIk0yIikpCmBgYAoKIyMjIyAqKipGaW5hbCBwbG90KioqCmBgYHtyfQpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlX1M0LnBkZiIsCiAgICAgICB3aWR0aD0xNSwKICAgICAgIGhlaWdodD0xMCkKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfUzQucG5nIiwKICAgICAgIHdpZHRoPTE1LAogICAgICAgaGVpZ2h0PTEwKQpgYGAKCgojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyBGaWd1cmUgUzUKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0V9CgpwZXJzaXRlX25vcm0gfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBmaWx0ZXIodHlwZSA9PSAiZGVkdXBfVEUiKSB8PgogIGZpbHRlcih2aXJ1cyA9PSAiWmlrYV92aXJ1cyIpIHw+CiAgcmVuYW1lKFZpcmFsLmxvYWQgPSBgVmlyYWwgbG9hZGApIHw+CiAgZ2dwbG90KGFlcyh4ID0gc2l0ZSwgeSA9IGNvdmVyYWdlLCBmaWxsID0gQmFja2dyb3VuZCkpICsKICBnZW9tX2NvbCgpICsKICBmYWNldF93cmFwKFZpcmFsLmxvYWQgfiBTYW1wbGVfaWQsIGxhYmVsID0gbGFiZWxfcGFyc2VkKSArCiAgeWxhYigiQ292ZXJhZ2UiKSArCiAgZ2d0aXRsZSgiWmlrYSB2aXJ1cyAoZGVkdXBsaWNhdGVkKSIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJCYWNrZ3JvdW5kIikpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfeV9sb2cxMCgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xzMiwgbGFiZWxzID0gYygiTTEiLCAiTTIiKSkKCmBgYAoKIyMjIyoqKkZpbmFsIHBsb3QqKioKYGBge3J9CgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlX1M1LnBkZiIsCiAgICAgICB3aWR0aD0xNSwKICAgICAgIGhlaWdodD0xMCkKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfUzUucG5nIiwKICAgICAgIHdpZHRoPTE1LAogICAgICAgaGVpZ2h0PTEwKQoKYGBgCgoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMgRmlndXJlIFM2CmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlY2hvPUZBTFNFfQoKcGVyc2l0ZV9ub3JtIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZmlsdGVyKHR5cGUgPT0gImRlZHVwX1RFIikgfD4KICBmaWx0ZXIodmlydXMgPT0gIkh1bWFuX2FkZW5vdmlydXNfNDAiKSB8PgogIHJlbmFtZShWaXJhbC5sb2FkID0gYFZpcmFsIGxvYWRgKSB8PgogIGdncGxvdChhZXMoeCA9IHNpdGUsIHkgPSBjb3ZlcmFnZSwgZmlsbCA9IEJhY2tncm91bmQpKSArCiAgZ2VvbV9jb2woKSArCiAgZmFjZXRfd3JhcChWaXJhbC5sb2FkIH4gU2FtcGxlX2lkLCBsYWJlbCA9IGxhYmVsX3BhcnNlZCkgKwogIHlsYWIoIkNvdmVyYWdlIikgKwogIGdndGl0bGUoIkh1bWFuIEFkZW5vdmlydXMgKGRlZHVwbGljYXRlZCkiKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQodGl0bGUgPSAiQmFja2dyb3VuZCIpKSArCiB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfeV9sb2cxMCgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xzMiwgbGFiZWxzID0gYygiTTEiLCAiTTIiKSkKCmBgYAoKIyMjIyoqKkZpbmFsIHBsb3QqKioKYGBge3J9CgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlX1M2LnBkZiIsCiAgICAgICB3aWR0aD0xNSwKICAgICAgIGhlaWdodD0xMCkKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfUzYucG5nIiwKICAgICAgIHdpZHRoPTE1LAogICAgICAgaGVpZ2h0PTEwKQoKYGBgCgoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMgRmlndXJlIFM3CmBgYHtyfQpIQlYgPC0gCnBlcnNpdGVfbm9ybSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGZpbHRlcih0eXBlID09ICJkZWR1cF9URSIpIHw+CiAgZmlsdGVyKHZpcnVzID09ICJIdW1hbl9iZXRhaGVycGVzdmlydXMiKSB8PgogIHJlbmFtZShWaXJhbC5sb2FkID0gYFZpcmFsIGxvYWRgKSB8PgogIGdncGxvdChhZXMoeCA9IHNpdGUsIHkgPSBjb3ZlcmFnZSwgZmlsbCA9IEJhY2tncm91bmQpKSArCiAgZ2VvbV9jb2woKSArCiAgZmFjZXRfd3JhcChWaXJhbC5sb2FkIH4gU2FtcGxlX2lkLCBsYWJlbCA9IGxhYmVsX3BhcnNlZCkgKwogIHlsYWIoIkNvdmVyYWdlIikgKwogIGdndGl0bGUoIkh1bWFuIEJldGFoZXJwZXN2aXJ1cyAoZGVkdXBsaWNhdGVkKSIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJCYWNrZ3JvdW5kIikpICsKIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV95X2xvZzEwKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbHMyLCBsYWJlbHMgPSBjKCJNMSIsICJNMiIpKQoKYGBgCgojIyMjKioqRmluYWwgcGxvdCoqKgpgYGB7cn0KCmdnc2F2ZShwbG90ID0gSEJWLCBmaWxlPSJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUERGL0ZpZ3VyZV9TNy5wZGYiLAogICAgICAgd2lkdGg9MTUsCiAgICAgICBoZWlnaHQ9MTAsCiAgICAgICBkcGkgPSA2MDApCgpnZ3NhdmUocGxvdCA9IEhCViwgZmlsZT0iZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfUzcucG5nIiwKICAgICAgIHdpZHRoPTE1LAogICAgICAgaGVpZ2h0PTEwKQoKCmBgYAoKCgojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyBGaWd1cmUgUzgKYGBge3J9CiNoYXZlIHRvIGRvIHRoZXNlIGRpZmZlcmVudGx5IGR1ZSB0byBzZWdtZW50YXRpb24KCkZMVV9NRTEgPC0gcGVyc2l0ZV9ub3JtIHw+CiAgZmlsdGVyKHZpcnVzID09ICJJbmZsdWVuemFfQl92aXJ1cyIpIHw+CiAgZmlsdGVyKHR5cGUgPT0gImRlZHVwX1RFIikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCA9PSAicDIiKSB8PgogIHJlbmFtZShWaXJhbC5sb2FkID0gYFZpcmFsIGxvYWRgKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gc2l0ZSwKICAgIHkgPSBjb3ZlcmFnZSwKICAgIGZpbGwgPSBhcy5jaGFyYWN0ZXIoVmlyYWwubG9hZCkKICApKSArCiAgZ2VvbV9jb2woKSArCiAgZmFjZXRfZ3JpZChzZWcgfiBTYW1wbGVfaWQpICsKICB5bGFiKCJDb3ZlcmFnZSIpICsKICBnZ3RpdGxlKCJJbmZsdWVuemEgQiB2aXJ1cyAoQmFja2dyb3VuZCBNMSBkZWR1cGxpY2F0ZWQpIikgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHRpdGxlID0gIlZpcmFsIGxvYWQiKSkgKwogdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX3lfbG9nMTAoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sczQsIGxhYmVsID0gYyhleHByZXNzaW9uKCIxMCJeIjIiKSwgZXhwcmVzc2lvbigiMTAiXiIzIiksIGV4cHJlc3Npb24oIjEwIl4iNSIpKSkKCkZMVV9NRTIgPC0gcGVyc2l0ZV9ub3JtIHw+CiAgZmlsdGVyKHZpcnVzID09ICJJbmZsdWVuemFfQl92aXJ1cyIpIHw+CiAgZmlsdGVyKHR5cGUgPT0gImRlZHVwX1RFIikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCA9PSAicDgiKSB8PgogIHJlbmFtZShWaXJhbC5sb2FkID0gYFZpcmFsIGxvYWRgKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gc2l0ZSwKICAgIHkgPSBjb3ZlcmFnZSwKICAgIGZpbGwgPSBhcy5jaGFyYWN0ZXIoVmlyYWwubG9hZCkKICApKSArCiAgZ2VvbV9jb2woKSArCiAgZmFjZXRfZ3JpZChzZWcgfiBTYW1wbGVfaWQpICsKICB5bGFiKCJDb3ZlcmFnZSIpICsKICBnZ3RpdGxlKCJJbmZsdWVuemEgQiB2aXJ1cyAoQmFja2dyb3VuZCBNMiBkZWR1cGxpY2F0ZWQpIikgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHRpdGxlID0gIlZpcmFsIGxvYWQiKSkgKwogdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX3lfbG9nMTAoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sczQsIGxhYmVsID0gYyhleHByZXNzaW9uKCIxMCJeIjIiKSwgZXhwcmVzc2lvbigiMTAiXiIzIiksIGV4cHJlc3Npb24oIjEwIl4iNSIpKSkKCgpnZ2FycmFuZ2UoRkxVX01FMSwgRkxVX01FMiwgbmNvbCA9IDIsIGNvbW1vbi5sZWdlbmQgPSBUUlVFKQoKYGBgCgojIyMjKioqRmluYWwgcGxvdCoqKgpgYGB7cn0KCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BERi9GaWd1cmVfUzgucGRmIiwKICAgICAgIHdpZHRoPTIwLAogICAgICAgaGVpZ2h0PTEyLAogICAgICAgZHBpPTYwMCkKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfUzgucG5nIiwKICAgICAgIHdpZHRoPTIwLAogICAgICAgaGVpZ2h0PTEyKQpgYGAKCgojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyBGaWd1cmUgUzkKYGBge3J9CgpSRU9fTUUxIDwtIAogIHBlcnNpdGVfbm9ybSB8PgogIGZpbHRlcih2aXJ1cyA9PSAiTWFtbWFsaWFuX29ydGhvcmVvdmlydXMzIikgfD4KICBmaWx0ZXIodHlwZSA9PSAiZGVkdXBfVEUiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kID09ICJwMiIpIHw+CiAgcmVuYW1lKFZpcmFsLmxvYWQgPSBgVmlyYWwgbG9hZGApIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBzaXRlLAogICAgeSA9IGNvdmVyYWdlLAogICAgZmlsbCA9IGFzLmNoYXJhY3RlcihWaXJhbC5sb2FkKQogICkpICsKICBnZW9tX2NvbCgpICsKICBmYWNldF9ncmlkKHNlZyB+IFNhbXBsZV9pZCkgKwogIHlsYWIoIkNvdmVyYWdlIikgKwogIGdndGl0bGUoIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMgKEJhY2tncm91bmQgTTEgZGVkdXBsaWNhdGVkKSIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJWaXJhbCBsb2FkIikpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGggPSAwLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGggPSAwLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfeV9sb2cxMCgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xzNCwKICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IGMoCiAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uKCIxMCIgXiAiMiIpLAogICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbigiMTAiIF4gIjMiKSwKICAgICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb24oIjEwIiBeICI1IikKICAgICAgICAgICAgICAgICAgICApKQoKUkVPX01FMiA8LSAKICBwZXJzaXRlX25vcm0gfD4KICBmaWx0ZXIodmlydXMgPT0gIk1hbW1hbGlhbl9vcnRob3Jlb3ZpcnVzMyIpIHw+CiAgZmlsdGVyKHR5cGUgPT0gImRlZHVwX1RFIikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCA9PSAicDgiKSB8PgogIHJlbmFtZShWaXJhbC5sb2FkID0gYFZpcmFsIGxvYWRgKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gc2l0ZSwKICAgIHkgPSBjb3ZlcmFnZSwKICAgIGZpbGwgPSBhcy5jaGFyYWN0ZXIoVmlyYWwubG9hZCkKICApKSArCiAgZ2VvbV9jb2woKSArCiAgZmFjZXRfZ3JpZChzZWcgfiBTYW1wbGVfaWQpICsKICB5bGFiKCJDb3ZlcmFnZSIpICsKICBnZ3RpdGxlKCJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIChCYWNrZ3JvdW5kIE0yIGRlZHVwbGljYXRlZCkiKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQodGl0bGUgPSAiVmlyYWwgbG9hZCIpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKyBzY2FsZV95X2xvZzEwKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbHM0LAogICAgICAgICAgICAgICAgICAgIGxhYmVsID0gYygKICAgICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb24oIjEwIiBeICIyIiksCiAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uKCIxMCIgXiAiMyIpLAogICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbigiMTAiIF4gIjUiKQogICAgICAgICAgICAgICAgICAgICkpCgpnZ2FycmFuZ2UoUkVPX01FMSwgUkVPX01FMiwgbmNvbCA9IDIsIGNvbW1vbi5sZWdlbmQgPSBUUlVFKQoKYGBgCgojIyMjKioqRmluYWwgcGxvdCoqKgpgYGB7cn0KZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUERGL0ZpZ3VyZV9TOS5wZGYiLAogICAgICAgd2lkdGg9MjAsCiAgICAgICBoZWlnaHQ9MTIsCiAgICAgICBkcGk9NjAwKQoKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUE5HL0ZpZ3VyZV9TOS5wbmciLAogICAgICAgd2lkdGg9MjAsCiAgICAgICBoZWlnaHQ9MTIsCiAgICAgICBkcGk9NjAwKQpgYGAKCgoKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgPj4+PiBGaWd1cmUgMzogYWxsIHZpcnVzZXMgLSB0YXJnZXQgYW5kIG9mZiB0YXJnZXQKCiMjIyBSZWFkLWluIGRhdGEKYGBge3J9CgojIHJlYWQgaW4gbWV0YWRhdGEKCm1ldGFkYXRhIDwtCiAgcmVhZC5jc3YoIm1ldGFkYXRhL3NhbXBsZUlEc19URVNwaWtlSW4uY3N2IiwgaGVhZGVyID0gVFJVRSkKCm1ldGFkYXRhMiA8LQogIG1ldGFkYXRhIHw+CiAgc2VsZWN0KAogICAgU2FtcGxlLklELAogICAgQmFja2dyb3VuZC5zYW1wbGUsCiAgICBWaXJhbC5sb2FkLAogICAgTnVtYmVyLm9mLnJlYWQucGFpcnMuLnF1YWxpdHkuYWRhcHRvci50cmltbWVkLgogICkgfD4KICByZW5hbWUoU2FtcGxlX2lkID0gU2FtcGxlLklEKSB8PgogIHJlbmFtZShRQ19yZWFkcyA9IE51bWJlci5vZi5yZWFkLnBhaXJzLi5xdWFsaXR5LmFkYXB0b3IudHJpbW1lZC4pCgojaW1wb3J0IHZpcmFsIHJlYWRzIG1hcHBlZCAodG8gY2FsY3VsYXRlIHByb3BvcnRpb25zKQoKdmlyYWxfcmVhZHNfZGVkdXAgPC0KICByZWFkLmNzdigKICAgICJkYXRhX1RFL3RvdGFsX3ZpcnVzX21hcHBlZF9yZWFkc19wZXJfc2FtcGxlX2RlZHVwX2F0Y2NfcmVmXzIwMjQxMTA4LmNzdiIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKdmlyYWxfcmVhZHNfbm9kZWR1cCA8LQogIHJlYWQuY3N2KAogICAgImRhdGFfVEUvdG90YWxfdmlydXNfbWFwcGVkX3JlYWRzX3Blcl9zYW1wbGVfbm9kZWR1cF9hdGNjX3JlZl8yMDI0MTEwOC5jc3YiLAogICAgaGVhZGVyID0gVFJVRQogICkKCiNpbXBvcnQgY29udGluZ2VuY3kgdGFibGVzCgpjb250aW5nZW5jeV9kZWR1cCA8LQogIHJlYWQuY3N2KAogICAgImRhdGFfVEUvY29udGluZ2VuY3lfdGFibGVfbWFwcGVkX3ZpcnVzX3JlYWRzX3Blcl9mYW1pbHlfZ2VudXNfc2FtcGxlX2RlZHVwX2F0Y2NfcmVmXzIwMjQxMTA2LmNzdiIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKY29udGluZ2VuY3lfbm9kZWR1cCA8LQogIHJlYWQuY3N2KAogICAgImRhdGFfVEUvY29udGluZ2VuY3lfdGFibGVfbWFwcGVkX3ZpcnVzX3JlYWRzX3Blcl9mYW1pbHlfZ2VudXNfc2FtcGxlX25vZGVkdXBfYXRjY19yZWZfMjAyNDExMDYuY3N2IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpjb250YW1pbmFudHMgPC0KICBjKCJCZXRhY29yb25hdmlydXMiLCAiQWxwaGFpbmZsdWVuemF2aXJ1cyIsICJHYW1tYXJldHJvdmlydXMiKQoKYGBgCgojIyMgRm9ybWF0IGRhdGEKYGBge3J9CgojIHBpdm90IGxvbmdlciAgCmRlZHVwX2xvbmcgPC0KICBjb250aW5nZW5jeV9kZWR1cCB8PgogIGZpbHRlcighZ2VudXMgJWluJSBjb250YW1pbmFudHMpIHw+CiAgZmlsdGVyKGdlbnVzICE9ICJOQSIpIHw+CiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBBOlAsCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gIlNhbXBsZV9pZCIsCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJjb3VudCIpIHw+CiAgbXV0YXRlKAogICAgdGFyZ2V0ID0gY2FzZV93aGVuKAogICAgICBnZW51cyA9PSAiQ3ljbG92aXJ1cyIgfiAib2ZmX3RhcmdldCIsCiAgICAgIGdlbnVzID09ICJDYXJkaW92aXJ1cyIgfiAib2ZmX3RhcmdldCIsCiAgICAgIGdlbnVzID09ICJLb2J1dmlydXMiIH4gIm9mZl90YXJnZXQiLAogICAgICAuZGVmYXVsdCA9ICJvbl90YXJnZXQiCiAgICApCiAgKSB8PgogIG11dGF0ZShnZW5vbWVfc3RydWN0dXJlID0gCiAgICAgICAgICAgY2FzZV93aGVuKChnZW51cyA9PSAiTWFzdGFkZW5vdmlydXMiIHwgCiAgICAgICAgICAgICAgICAgICAgICAgIGdlbnVzID09ICJDeXRvbWVnYWxvdmlydXMiIHwgCiAgICAgICAgICAgICAgICAgICAgICAgIGdlbnVzID09ICJDeWNsb3ZpcnVzIiB+ICJETkEiKSwKICAgICAgICAgICAgICAgICAgICAgLmRlZmF1bHQgPSAiUk5BIgogICkpCgpub19kZWR1cF9sb25nIDwtIGNvbnRpbmdlbmN5X25vZGVkdXAgfD4KICBmaWx0ZXIoIWdlbnVzICVpbiUgY29udGFtaW5hbnRzKSB8PgogIGZpbHRlcihnZW51cyAhPSAiTkEiKSB8PgogIHBpdm90X2xvbmdlcihjb2xzID0gQTpQLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJTYW1wbGVfaWQiLAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiY291bnQiKSB8PgogIG11dGF0ZSgKICAgIHRhcmdldCA9IGNhc2Vfd2hlbigKICAgICAgZ2VudXMgPT0gIkN5Y2xvdmlydXMiIH4gIm9mZl90YXJnZXQiLAogICAgICBnZW51cyA9PSAiQ2FyZGlvdmlydXMiIH4gIm9mZl90YXJnZXQiLAogICAgICBnZW51cyA9PSAiS29idXZpcnVzIiB+ICJvZmZfdGFyZ2V0IiwKICAgICAgLmRlZmF1bHQgPSAib25fdGFyZ2V0IgogICAgKQogICkgfD4KICBtdXRhdGUoZ2Vub21lX3N0cnVjdHVyZSA9IAogICAgICAgICAgIGNhc2Vfd2hlbigoZ2VudXMgPT0gIk1hc3RhZGVub3ZpcnVzIiB8IAogICAgICAgICAgICAgICAgICAgICAgICBnZW51cyA9PSAiQ3l0b21lZ2Fsb3ZpcnVzIiB8IAogICAgICAgICAgICAgICAgICAgICAgICBnZW51cyA9PSAiQ3ljbG92aXJ1cyIgfiAiRE5BIiksCiAgICAgICAgICAgICAgICAgICAgIC5kZWZhdWx0ID0gIlJOQSIKICApKQoKbWV0YWRhdGFfZGVkdXAgPC0gbGVmdF9qb2luKGRlZHVwX2xvbmcsIG1ldGFkYXRhMiwgYnkgPSAiU2FtcGxlX2lkIikKCmRlZHVwX3ZpcmFsX3JlYWRzIDwtCiAgbGVmdF9qb2luKG1ldGFkYXRhX2RlZHVwLCB2aXJhbF9yZWFkc19kZWR1cCwgYnkgPSAiU2FtcGxlX2lkIikgfD4KICBtdXRhdGUodG90YWxfcmVhZHMgPSBRQ19yZWFkcyAqIDIpIHw+CiAgbXV0YXRlKHByb3BfdG90YWwgPSBjb3VudCAvIHRvdGFsX3JlYWRzKSB8PgogIG11dGF0ZShwcm9wX3ZpcmFsID0gY291bnQgLyB0b3RhbF92aXJ1c19yZWFkcykKCm1ldGFkYXRhX25vX2RlZHVwIDwtIGxlZnRfam9pbihub19kZWR1cF9sb25nLCBtZXRhZGF0YTIsIGJ5ID0gIlNhbXBsZV9pZCIpCgpub2RlZHVwX3ZpcmFsX3JlYWRzIDwtCiAgbGVmdF9qb2luKG1ldGFkYXRhX25vX2RlZHVwLCB2aXJhbF9yZWFkc19ub2RlZHVwLCBieSA9ICJTYW1wbGVfaWQiKSB8PgogIG11dGF0ZSh0b3RhbF9yZWFkcyA9IFFDX3JlYWRzICogMikgfD4KICBtdXRhdGUocHJvcF90b3RhbCA9IGNvdW50IC8gdG90YWxfcmVhZHMpIHw+CiAgbXV0YXRlKHByb3BfdmlyYWwgPSBjb3VudCAvIHRvdGFsX3ZpcnVzX3JlYWRzKQoKYGBgCgojIyMgTWFrZSBwbG90cwpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZWNobz1GQUxTRX0KCmZhY2V0X25hbWVzIDwtIGMoCiAgIk1zcF9wMiIgPSAiTTEiLAogICJNc3BfcDgiID0gIk0yIiwKICAib2ZmX3RhcmdldCIgPSAiQmFja2dyb3VuZCIsCiAgIm9uX3RhcmdldCIgPSAiU3Bpa2UtaW4iCikKCmNvbHMgPC0KICBjKAogICAgIiNDQ0JCNDQiLAogICAgIiMzMzIyODgiLAogICAgIiNFRTc3MzMiLAogICAgIiM2NkNDRUUiLAogICAgIiM4ODIyNTUiLAogICAgIiM0NDc3QUEiLAogICAgIiNBQTMzNzciLAogICAgIiMyMjg4MzMiLAogICAgIiNFRTY2NzciCiAgKQoKCmRlZHVwX3JlYWRzIDwtIAogIGRlZHVwX3ZpcmFsX3JlYWRzIHw+CiAgZmlsdGVyKEJhY2tncm91bmQuc2FtcGxlICE9ICJOZWdfY29udHJvbCIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQuc2FtcGxlICE9ICJNc3BfcDYiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gVmlyYWwubG9hZCwKICAgIHkgPSAoY291bnQpLAogICAgY29sb3VyID0gZ2VudXMKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBnZW51cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQodGFyZ2V0IH4gQmFja2dyb3VuZC5zYW1wbGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXMpKSArCiAgdGhlbWVfZmV3KCkgKyAKICBzY2FsZV94X2xvZzEwKCkgKwogIHNjYWxlX3lfbG9nMTAoKSArCiAgeWxhYigiVmlyYWwgUmVhZHMiKSArIAogIHhsYWIoIkdlbm9tZSBjb3BpZXMiKSArIAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzKSArCiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcz1jKCJkb3R0ZWQiLCAic29saWQiKSkgKyAKICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkgKyAKICAgIHNjYWxlX3lfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICMgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApCgpkZWR1cF9wcm9wX3ZpcmFsIDwtCiAgZGVkdXBfdmlyYWxfcmVhZHMgfD4KICBmaWx0ZXIoQmFja2dyb3VuZC5zYW1wbGUgIT0gIk5lZ19jb250cm9sIikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZC5zYW1wbGUgIT0gIk1zcF9wNiIpIHw+CiAgZ2dwbG90KGFlcyh4ID0gVmlyYWwubG9hZCwgeSA9IHByb3BfdmlyYWwsIGNvbG91ciA9IGdlbnVzKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gZ2VudXMsIGxpbmV0eXBlID0gZ2Vub21lX3N0cnVjdHVyZSksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKHRhcmdldCB+IEJhY2tncm91bmQuc2FtcGxlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsgCiAgc2NhbGVfeF9sb2cxMCgpICsKICBzY2FsZV95X2xvZzEwKCkgKwogIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkgKyAKICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZXM6OmxhYmVsX21hdGgoKSkpICsKICBzY2FsZV9saW5ldHlwZV9tYW51YWwodmFsdWVzPWMoImRvdHRlZCIsICJzb2xpZCIpKSArIAogIHlsYWIoIlByb3BvcnRpb24gb2YgdmlyYWwgcmVhZHMiKSArCiAgeGxhYigiR2Vub21lIGNvcGllcyIpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbHMpICsKICAgIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAjIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKQoKZGVkdXBfcHJvcF9hbGwgPC0KICBkZWR1cF92aXJhbF9yZWFkcyB8PgogIGZpbHRlcihCYWNrZ3JvdW5kLnNhbXBsZSAhPSAiTmVnX2NvbnRyb2wiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kLnNhbXBsZSAhPSAiTXNwX3A2IikgfD4KICBnZ3Bsb3QoYWVzKHggPSBWaXJhbC5sb2FkLCB5ID0gcHJvcF90b3RhbCwgY29sb3VyID0gZ2VudXMpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBnZW51cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQodGFyZ2V0IH4gQmFja2dyb3VuZC5zYW1wbGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXMpKSArCiAgdGhlbWVfZmV3KCkgKyAKICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZXM6OmxhYmVsX21hdGgoKSkpICsgCiAgc2NhbGVfeV9sb2cxMChsaW1pdHMgPSBjKDVlLTgsIDEpLCBicmVha3MgPSAxMCoqKHNlcSgtNiwwLDIpKSxsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKSArCiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcz1jKCJkb3R0ZWQiLCAic29saWQiKSkgKyAKICB5bGFiKCJQcm9wb3J0aW9uIG9mIHRvdGFsIHJlYWRzIikgKwogIHhsYWIoIkdlbm9tZSBjb3BpZXMiKSArIAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzKSArCiAgICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDEpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApCgoKYGBgCgojIyMgRGVkdXAgLS0gdmlyYWwgcmVhZHMsIHByb3AgYWxsIHJlYWRzLCBhbmQgcHJvcCB2aXJhbCByZWFkcwpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZWNobz1GQUxTRSwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9MTJ9CgpnZ2FycmFuZ2UoCiAgZGVkdXBfcmVhZHMsCiAgZGVkdXBfcHJvcF9hbGwsCiAgZGVkdXBfcHJvcF92aXJhbCwKICBucm93ID0gMywKICBjb21tb24ubGVnZW5kID0gVFJVRSwKICBhbGlnbiA9ICJodiIKKQoKYGBgCgojIyMgKioqRmluYWwgcGxvdCoqKgoKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0UsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTh9CgoKIyNqdXN0IHBsb3QgdmlyYWwgcmVhZHMgYW5kIHByb3AgdmlyYWwKCmdnYXJyYW5nZSgKICBkZWR1cF9yZWFkcywKICBkZWR1cF9wcm9wX3ZpcmFsLAogIG5yb3cgPSAyLAogIGNvbW1vbi5sZWdlbmQgPSBUUlVFLAogIGFsaWduID0gImh2IgopCgojIGdnc2F2ZSgiZmlndXJlcy9jb21wYXJlX3NwaWtlX2luc19hdGNjL3RhcmdldF9vZmZ0YXJnZXRfZGVkdXBfMjAyNS0wMS0wMS5wbmciLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA4KQoKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUERGL0ZpZ3VyZV8zLnBkZiIsIAogICAgICAgd2lkdGggPSAxMCwgaGVpZ2h0ID0gOCkKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfMy5wbmciLCAKICAgICAgIHdpZHRoID0gMTAsIGhlaWdodCA9IDgpCmBgYAojIyMgLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLgojIyMgLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLgoKIyMjIC0tLS1HZW5vbWUgbWVkaWNpbmUgcmVzdWx0cy0tLS0KIyMjIEZpZ3VyZSBTMTAKCiMjIyMgUmVhZC1pbiBkYXRhCmBgYHtyfQoKCiMjIyNyZWFkIGNvdW50cy9ub3JtYWxpc2VkIHJlYWQgY291bnRzIyMjIwoKI2ltcG9ydCBhbmQgY29tYmluZSByZWFkIGNvdW50IGZpbGVzCgpnbV9yZWFkY291bnRfZGVkdXAgPC0KICByZWFkLnRhYmxlKAogICAgImRhdGFfZ2Vub21lX21lZGljaW5lL2dlbm9tZV9tZWRpY2luZV9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGNvdW50X3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKZ21fcmVhZGNvdW50X25vZGVkdXAgPC0KICByZWFkLnRhYmxlKAogICAgImRhdGFfZ2Vub21lX21lZGljaW5lL2dlbm9tZV9tZWRpY2luZV9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGNvdW50X3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfbm9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpnbV9jb3VudHNfYWxsIDwtIHJiaW5kKGdtX3JlYWRjb3VudF9kZWR1cCwgZ21fcmVhZGNvdW50X25vZGVkdXApCgpgYGAKCiMjIyMgcmVhZCBjb3VudHMgCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojbm9ybWFsaXNlIGJ5IGJvdGggcmF3IHJlYWQgY291bnQgYW5kIGdlbm9tZSBsZW5ndGggLSBzaG91bGQgYmUgdGhlIHNhbWUgYXMgbWVhbiByZWFkIGRlcHRoCgpmYWNldF9uYW1lcyA8LSBjKCJkZWR1cF9HTV9URSIgPSAiRGVkdXBsaWNhdGVkIiwKICAgICAgICAgICAgICAgICAibm9kZWR1cF9HTV9URSIgPSAiTm9uLURlZHVwbGljYXRlZCIpCgpjb2xzIDwtIGMoIiM0NDc3QUEiLAogICAgICAgICAgIiM2NkNDRUUiLAogICAgICAgICAgIiMyMjg4MzMiLAogICAgICAgICAgIiNDQ0JCNDQiLAogICAgICAgICAgIiNFRTY2NzciLAogICAgICAgICAgIiNBQTMzNzciKQoKZ21fY291bnRzX25vcm0gPC0gCiAgZ21fY291bnRzX2FsbCB8PgogIG11dGF0ZShub3JtX2NvdW50czMgPSBtYXRjaGVkIC8gbGVuZ3RoKQoKcmVhZF9jb3VudHMgPC0gCiAgZ21fY291bnRzX25vcm0gfD4KICBmaWx0ZXIoVmlyYWwubG9hZCAhPSAwKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gVmlyYWwubG9hZCwKICAgIHkgPSAobWF0Y2hlZCksCiAgICBjb2xvdXIgPSB2aXJ1cwogICkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IHZpcnVzKSwgc2UgPSBGQUxTRSwgc3BhbiA9IDAuODUpICsKICBmYWNldF9ncmlkKCB+IHR5cGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXMpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAjIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGggPSAwLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGggPSAwLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKAogICAgdmFsdWVzID0gY29scywKICAgIGxhYmVscyA9IGMoCiAgICAgICJIdW1hbiBhZGVub3ZpcnVzIDQwIiwKICAgICAgIkh1bWFuIGJldGFoZXJwZXN2aXJ1cyIsCiAgICAgICJIdW1hbiByZXNwaXJhdG9yeSBzeW5jeXRpYWwgdmlydXMiLAogICAgICAiSW5mbHVlbnphIEIgdmlydXMiLAogICAgICAiTWFtbWFsaWFuIG9ydGhvcmVvdmlydXMgMyIsCiAgICAgICJaaWthIHZpcnVzIgogICAgKQogICkgKwogIHlsYWIoIlZpcmFsIFJlYWRzIikgKwogIHhsYWIoIkdlbm9tZSBjb3BpZXMiKSArIAogIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkgKyAKICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZXM6OmxhYmVsX21hdGgoKSkpCgpgYGAKCiMjIyMgcmVhZCBkZXB0aApgYGB7cn0KI2ltcG9ydCBhbmQgY29tYmluZSByZWFkIGRlcHRoIGZpbGVzCgpkZXB0aF9kZWR1cF9nbSA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9nZW5vbWVfbWVkaWNpbmUvZ2Vub21lX21lZGljaW5lX1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpkZXB0aF9ub2RlZHVwX2dtIDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX2dlbm9tZV9tZWRpY2luZS9nZW5vbWVfbWVkaWNpbmVfVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRkZXB0aF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX25vZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKZGVwdGhzX2dtX2FsbCA8LSByYmluZChkZXB0aF9kZWR1cF9nbSwgZGVwdGhfbm9kZWR1cF9nbSkKCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CgpyZWFkX2RlcHRocyA8LSAKICBkZXB0aHNfZ21fYWxsIHw+CiAgZmlsdGVyKFZpcmFsLmxvYWQgIT0gMCkgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IFZpcmFsLmxvYWQsCiAgICB5ID0gbWVhbl9kZXB0aCwKICAgIGNvbG91ciA9IHZpcnVzCiAgKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gdmlydXMpLCBzZSA9IEZBTFNFLCBzcGFuID0gMC45KSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgIHZhbHVlcyA9IGNvbHMsCiAgICBsYWJlbHMgPSBjKAogICAgICAiSHVtYW4gYWRlbm92aXJ1cyA0MCIsCiAgICAgICJIdW1hbiBiZXRhaGVycGVzdmlydXMiLAogICAgICAiSHVtYW4gcmVzcGlyYXRvcnkgc3luY3l0aWFsIHZpcnVzIiwKICAgICAgIkluZmx1ZW56YSBCIHZpcnVzIiwKICAgICAgIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMiLAogICAgICAiWmlrYSB2aXJ1cyIKICAgICkKICApICsKICB5bGFiKCJNZWFuIHJlYWQgZGVwdGgiKSArCiAgeGxhYigiR2Vub21lIGNvcGllcyIpICsgCiAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKSArIAogIHNjYWxlX3lfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkKCgoKYGBgCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCmdnYXJyYW5nZShyZWFkX2NvdW50cywKICAgICAgICAgIHJlYWRfZGVwdGhzLAogICAgICAgICAgbnJvdyA9IDIsCiAgICAgICAgICBjb21tb24ubGVnZW5kID0gVFJVRSkKCgojUERGCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BERi9GaWd1cmVfUzEwLnBkZiIsIAogICAgICAgd2lkdGggPSA3LAogICAgICAgaGVpZ2h0ID0gNykKCiNQTkcKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUE5HL0ZpZ3VyZV9TMTAucG5nIiwgCiAgICAgICB3aWR0aCA9IDcsCiAgICAgICBoZWlnaHQgPSA3KQoKYGBgCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIEZpZ3VyZSBTMTEKCiMjIyMgUmVhZC1pbiBkYXRhCmBgYHtyfQojIyMjZ2Vub21lIGNvdmVyYWdlIyMjIwoKdW56aXAoemlwZmlsZSA9ICJkYXRhX2dlbm9tZV9tZWRpY2luZS9nZW5vbWVfbWVkaWNpbmVfVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRkZXB0aF9wZXJfc2l0ZV9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfZGVkdXBfYXRjY19yZWYudHN2LnppcCIsIGV4ZGlyID0gImRhdGFfZ2Vub21lX21lZGljaW5lLyIpCgpkZWR1cF9wZXJfc2l0ZSA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9nZW5vbWVfbWVkaWNpbmUvZ2Vub21lX21lZGljaW5lX1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NpdGVfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX2RlZHVwX2F0Y2NfcmVmLnRzdiIsCiAgICBzZXAgPSAiXHQiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmZpbGUucmVtb3ZlKCJkYXRhX2dlbm9tZV9tZWRpY2luZS9nZW5vbWVfbWVkaWNpbmVfVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRkZXB0aF9wZXJfc2l0ZV9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfZGVkdXBfYXRjY19yZWYudHN2IikKCiNWaWV3KGRlZHVwX3Blcl9zaXRlKQoKY291bnRzX2RlZHVwX2J0IDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkY291bnRfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgojYWRkIGxlbmd0aCBjb2x1bW4gZnJvbSByZWFkIGRlcHRoIGZpbGUgdG8gcGVyIHNpdGUgZmlsZQoKbGVuZ3RocyA8LSAKICBjb3VudHNfZGVkdXBfYnQgfD4KICBzZWxlY3QodmlydXMsbGVuZ3RoKSB8PgogIGRpc3RpbmN0KCkKCiNjYWxjdWxhdGUgZ2Vub21lIGNvdmVyYWdlCgpjb3ZlcmFnZSA8LSAKICBkZWR1cF9wZXJfc2l0ZSB8PgogIGdyb3VwX2J5KHNhbXBsZV9pZCwgdmlydXMsIFZpcmFsLmxvYWQsIFJlcGxpY2F0ZSkgfD4KICBmaWx0ZXIoY292ZXJhZ2UgPiAwKSB8PgogIHN1bW1hcmlzZShnZW5vbWVfY292ZXJhZ2UgPSBuKCkpIHw+CiAgbGVmdF9qb2luKGxlbmd0aHMpIHw+CiAgbXV0YXRlKHBlcmNlbnRfY292ZXJhZ2UgPSBnZW5vbWVfY292ZXJhZ2UgLyBsZW5ndGgpCgpjb3ZlcmFnZSB8PgogIGZpbHRlcihWaXJhbC5sb2FkICE9IDApIHw+CiAgZ2dwbG90KGFlcyh4ID0gdmlydXMsIHkgPSBwZXJjZW50X2NvdmVyYWdlKSkgKwogIGdlb21fYm94cGxvdChvdXRsaWVyLnNoYXBlID0gTkEpICsKICBnZW9tX3BvaW50KHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAuNzUpKSArCiAgZmFjZXRfZ3JpZCggfiBhcy5jaGFyYWN0ZXIoVmlyYWwubG9hZCkpICsKICB0aGVtZV9idygpICsKICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKwogIHlsYWIoIkdlbm9tZSBjb3ZlcmFnZSIpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGggPSAwLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGggPSAwLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMSkpICsKICAgIHNjYWxlX3hfZGlzY3JldGUoCiAgICBsYWJlbHMgPSBjKAogICAgICAiSHVtYW4gYWRlbm92aXJ1cyA0MCIsCiAgICAgICJIdW1hbiBiZXRhaGVycGVzdmlydXMiLAogICAgICAiSHVtYW4gcmVzcGlyYXRvcnkgc3luY3l0aWFsIHZpcnVzIiwKICAgICAgIkluZmx1ZW56YSBCIHZpcnVzIiwKICAgICAgIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMiLAogICAgICAiWmlrYSB2aXJ1cyIKICAgICkKICApCgojZ2dzYXZlKCIvVXNlcnMvbGF1cmEvRHJvcGJveC9nbGFzZ293L2dpdGh1Yi90ZV91Z19yb2RlbnRzL2ZpZ3VyZXMvZ2Vub21lX21lZGljaW5lL2FsbF9nZW5vbWVfY292ZXJhZ2UucG5nIix3aWR0aD0xNCxoZWlnaHQ9NikKCiNnZ3NhdmUoIi9Vc2Vycy9sYXVyYS9Ecm9wYm94L2dsYXNnb3cvZ2l0aHViL3RlX3VnX3JvZGVudHMvZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZXNfcGRmL0ZpZ3VyZVMxMi5wZGYiLHdpZHRoPTIwLGhlaWdodD02KQpgYGAKCiMjIyMgKioqIEZpbmFsIHBsb3QgKioqCmBgYHtyfQojUERGCmdnc2F2ZSgKICAiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BERi9GaWd1cmVfUzExLnBkZiIsCiAgd2lkdGggPSAxNCwKICBoZWlnaHQgPSA2CikKCiNQTkcKZ2dzYXZlKAogICJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUE5HL0ZpZ3VyZV9TMTEucG5nIiwKICB3aWR0aCA9IDE0LAogIGhlaWdodCA9IDYKKQoKYGBgCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIEZpZ3VyZSBTMTIKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMjIyNwZXIgc2l0ZSBwbG90IEFkViBvbmx5IyMjIwoKZGVkdXBfcGVyX3NpdGUgfD4KICBmaWx0ZXIodmlydXMgPT0gIkh1bWFuX2FkZW5vdmlydXNfNDAiKSB8PgogIGZpbHRlcihWaXJhbC5sb2FkICE9IDApIHw+CiAgZ2dwbG90KGFlcyh4PXNpdGUseT1jb3ZlcmFnZSkpKwogIGdlb21fY29sKCkrCiAgZmFjZXRfZ3JpZChWaXJhbC5sb2FkflJlcGxpY2F0ZSkrCiAgeWxhYigiQ292ZXJhZ2UgcGVyIHNpdGUiKSsKICBnZ3RpdGxlKCJIdW1hbiBBZGVub3ZpcnVzIChkZWR1cGxpY2F0ZWQpIikrCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgIyBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICMgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpLAogICAgIyBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICMgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgIyBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKyAgCiAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKSArCgogIHhsYWIoInNpdGUgcG9zaXRpb24iKQoKYGBgCgojIyMjICoqKiBGaW5hbCBwbG90ICoqKgpgYGB7cn0KZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUERGL0ZpZ3VyZV9TMTIucGRmIiwKICAgICAgIHdpZHRoPTEyLAogICAgICAgaGVpZ2h0PTEwKQoKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUE5HL0ZpZ3VyZV9TMTIucG5nIiwKICAgICAgIHdpZHRoPTEyLAogICAgICAgaGVpZ2h0PTEwKQpgYGAKIyMjIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4KCiMjIyAtLS0tS29idXZpcnVzIC8gQ2FyZGlvdmlydXMgcmVzdWx0cy0tLS0KCiMjIyMgRmlndXJlIFMxMwoKYGBge3J9Cgprb2J1X2RlcHRoIDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX2tvYnV2aXJ1cy9rb2J1dmlydXNfVEVfcG9seW9taWNzX3JlYWRkZXB0aF8yMDI0MTAwNy50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApICU+JQogIHNlbGVjdCghZXhwdCkgJT4lCiAgc2VsZWN0KCFOdW1iZXIub2YucGFpcmVkLmVuZC5yZWFkcy4uUVQuKQoKY2FyZGlvX2RlcHRoIDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX2NhcmRpb3ZpcnVzL2NhcmRpb3ZpcnVzX2Rlbm92b19ib3d0aWUyX3JlYWRfZGVwdGhfcGVyX3NhbXBsZV9kZWR1cC50c3YiLAogICAgc2VwID0gIiwiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmNhcmRpb19kZXB0aF9wb2x5IDwtIAogIHJlYWQudGFibGUoCiAgICAiZGF0YV9jYXJkaW92aXJ1cy9jYXJkaW92aXJ1c19kZW5vdm9fYm93dGllMl9yZWFkZGVwdGhfcGVyX3NhbXBsZV9kZWR1cF9wb2x5b21pY3MudHN2IiwKICAgIHNlcCA9ICIsIiwKICAgIGhlYWRlciA9IFRSVUUKICApIHw+CiAgc2VsZWN0KC1jb250aWdfbmFtZSkgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAlaW4lIGMoIlMxOCIsICJTMTkiLCAiUzQzIikpIHw+CiAgc2VsZWN0KC1CYWNrZ3JvdW5kKSB8PgogIHNlcGFyYXRlKFNhbXBsZV9pZCwgaW50byA9IGMoTkEsIE5BLCAiQmFja2dyb3VuZCIpLCBzZXAgPSAiLSIsIHJlbW92ZSA9IEZBTFNFKQoKZGVwdGhfYm90aCA8LSByYmluZChrb2J1X2RlcHRoLCBjYXJkaW9fZGVwdGgsIGNhcmRpb19kZXB0aF9wb2x5KSB8PgogIG11dGF0ZShWaXJhbC5sb2FkID0gaWZlbHNlKGlzLm5hKFZpcmFsLmxvYWQpLCAwLCBWaXJhbC5sb2FkKSkKCmRlcHRoX2JvdGgkdHlwZSA8LSBkZXB0aF9ib3RoJHR5cGUgfD4KICBjYXNlX21hdGNoKCJkZWR1cF9URSIgfiAiZGVkdXAiLAogICAgICAgICAgICAgImRlZHVwX3BvbHlvbWljcyIgfiAiZGVkdXAiLAogICAgICAgICAgICAgLmRlZmF1bHQgPSBkZXB0aF9ib3RoJHR5cGUpCgpkZXB0aF9ib3RoJFNhbXBsZV9pZCA8LSBkZXB0aF9ib3RoJFNhbXBsZV9pZCB8PgogIGNhc2VfbWF0Y2goIlJOQS1Nc3AtcDIiIH4gIk0xIiwKICAgICAgICAgICAgICJSTkEtTXNwLXA4IiB+ICJNMiIsCiAgICAgICAgICAgICAiUk5BLU1zcC1wNiIgfiAiTTMiLAogICAgICAgICAgICAgLmRlZmF1bHQgPSBkZXB0aF9ib3RoJFNhbXBsZV9pZAogICAgICAgICAgICAgKQoKZGVwdGhfYm90aCR2aXJ1cyA8LSBkZXB0aF9ib3RoJHZpcnVzIHw+CiAgY2FzZV9tYXRjaCgiY2FyZGlvdmlydXMiIH4gIkNhcmRpb3ZpcnVzIiwKICAgICAgICAgICAgICJrOTdfMTk5NzEiIH4gIktvYnV2aXJ1cyIsCiAgICAgICAgICAgICAuZGVmYXVsdCA9IGRlcHRoX2JvdGgkdmlydXMKICAgICAgICAgICAgICkKCmNvbHMyIDwtIGMoIiNCQjU1NjYiLCAiIzAwNDQ4OCIpCgpjb3ZlcmFnZV9sYWJlbHMgPC0gYygKICAiazk3XzE5OTcxIiA9ICJLb2J1dmlydXMiLAogICJjYXJkaW92aXJ1cyIgPSAiQ2FyZGlvdmlydXMiLAogICJwMiIgPSAiTTEiLAogICJwOCIgPSAiTTIiCikKCmBgYAoKIyMjIyAqKiogRmluYWwgcGxvdCAqKioKYGBge3J9CgpkZXB0aF9ib3RoJFZpcmFsLmxvYWQgPC0gZmFjdG9yKGRlcHRoX2JvdGgkVmlyYWwubG9hZCwgbGFiZWxzID0gYygiU2hvdGd1biIsCiAgICAiMTBeezJ9IiwgCiAgICAiMTBeezN9IiwgCiAgICAiMTBeezV9IgogICAgKSkKCgojIGRlcHRoX2JvdGggfD4KIyAgIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiMgICBmaWx0ZXIodHlwZSA9PSAiZGVkdXAiKSB8PgojICAgZmlsdGVyKG1hcHBlciA9PSAiYm93dGllMiIpIHw+CiMgICBmaWx0ZXIoVmlyYWwubG9hZCAhPSAiTkEiKSB8PgojICAgZ2dwbG90KGFlcygKIyAgICAgeCA9IFZpcmFsLmxvYWQsCiMgICAgIHkgPSAobWVhbl9kZXB0aCksCiMgICAgIGNvbG91ciA9IEJhY2tncm91bmQKIyAgICkpICsKIyAgIGdlb21fcG9pbnQoKSArCiMgIHRoZW1lX2ZldygpICsKIyAgIHRoZW1lKAojICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKIyAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiMgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKIyAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAKIyAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKIyAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQojICAgKSArICAKIyAgIGZhY2V0X2dyaWQoQmFja2dyb3VuZCB+IHZpcnVzLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGNvdmVyYWdlX2xhYmVscykpICsKIyAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMikgKwojICAgeWxhYigiTWVhbiByZWFkIGRlcHRoIikgKwojICAgICB4bGFiKCJTcGlrZS1pbiB2aXJhbCBsb2FkIChnYy9tbCkiKSArCiMgICAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZXM6OmxhYmVsX21hdGgoKSkpICsgCiMgICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkKCiMgcmVwbG90dGluZyBTMTMgaW4gc2ltaWxhciB3YXkgdG8gUzE0CmRlcHRoX2JvdGggJT4lCiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIodHlwZSA9PSAiZGVkdXAiKSB8PgogIGZpbHRlcihtYXBwZXIgPT0gImJvd3RpZTIiKSB8PgogICMgZmlsdGVyKFZpcmFsLmxvYWQgIT0gIk5BIikgfD4KICBnZ3Bsb3QoYWVzKHggPSBTYW1wbGVfaWQsIHkgPSBtZWFuX2RlcHRoLCBjb2xvciA9IEJhY2tncm91bmQpKSArCiAgZ2VvbV9wb2ludCgpICsKICB5bGFiKCJNZWFuIHJlYWQgZGVwdGgiKSArCiAgeGxhYigiU2FtcGxlIElEIikgKwogIGZhY2V0X2dyaWQodmlydXMgfiBWaXJhbC5sb2FkLAogICAgICAgICAgICAgc2NhbGVzID0gImZyZWVfeCIsCiAgICAgICAgICAgICBsYWJlbCA9IGxhYmVsX3BhcnNlZCkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMiwgbGFiZWxzID0gYygiTTEiLCAiTTIiKSkgKwogdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApKwogIHNjYWxlX3lfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkKCgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlX1MxM192Mi5wZGYiLAogICAgICAgd2lkdGg9OCwKICAgICAgIGhlaWdodD00KQoKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUE5HL0ZpZ3VyZV9TMTNfdjIucG5nIiwKICAgICAgIHdpZHRoPTgsCiAgICAgICBoZWlnaHQ9NCkKCmBgYAoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMjIEZpZ3VyZSBTMTQKCmBgYHtyfQoKa29idV9wZXJfc2l0ZSA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9rb2J1dmlydXMva29idXZpcnVzX1RFX3BvbHlvbWljc19yZWFkZGVwdGhfcGVyc2l0ZV8yMDI0MTAwNy50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApICU+JQogIHNlbGVjdCh2aXJ1cywKICAgICAgICAgc2VnLAogICAgICAgICBzaXRlLAogICAgICAgICBjb3ZlcmFnZSwKICAgICAgICAgbl9zaXRlcywKICAgICAgICAgU2FtcGxlX2lkLAogICAgICAgICBCYWNrZ3JvdW5kLAogICAgICAgICBWaXJhbC5sb2FkLAogICAgICAgICBtYXBwZXIsCiAgICAgICAgIHR5cGUpCgprb2J1X3Blcl9zaXRlJFZpcmFsLmxvYWQgPC0gCiAga29idV9wZXJfc2l0ZSRWaXJhbC5sb2FkICU+JQogIHJlcGxhY2VfbmEoLiwgMCkKCmtvYnVfcGVyX3NpdGUkU2FtcGxlX2lkIDwtIGtvYnVfcGVyX3NpdGUkU2FtcGxlX2lkICU+JQogIGNhc2VfbWF0Y2goIlJOQS1Nc3AtcDIiIH4gIk0xIiwKICAgICAgICAgICAgICJSTkEtTXNwLXA4IiB+ICJNMiIsCiAgICAgICAgICAgICAuZGVmYXVsdCA9IGtvYnVfcGVyX3NpdGUkU2FtcGxlX2lkKQoKa29idV9wZXJfc2l0ZSRCYWNrZ3JvdW5kIDwtIGtvYnVfcGVyX3NpdGUkQmFja2dyb3VuZCAlPiUKICBjYXNlX21hdGNoKCJwMiIgfiAiTTEiLAogICAgICAgICAgICAgInA4IiB+ICJNMiIsCiAgICAgICAgICAgICAuZGVmYXVsdCA9IGtvYnVfcGVyX3NpdGUkQmFja2dyb3VuZCkKCmNhcmRpb19wZXJfc2l0ZSA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9jYXJkaW92aXJ1cy9jYXJkaW92aXJ1c19kZW5vdm9fYm93dGllMl9yZWFkX2RlcHRoX3Blcl9zaXRlX2FuZF9zYW1wbGVfZGVkdXAudHN2IiwKICAgIHNlcCA9ICIsIiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpjYXJkaW9fcG9seW9taWNzX3Blcl9zaXRlIDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX2NhcmRpb3ZpcnVzL2NhcmRpb3ZpcnVzX2Rlbm92b19ib3d0aWUyX3JlYWRkZXB0aF9wZXJfc2l0ZV9zYW1wbGVfZGVkdXBfcG9seW9taWNzLnRzdiIsCiAgICBzZXAgPSAiLCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKSAlPiUKICBzZWxlY3QoIWNvbnRpZ19uYW1lKQoKI1ZpZXcoY2FyZGlvX3BvbHlvbWljc19wZXJfc2l0ZSkKCmNhcmRpb19URV9wb2x5b21pY3MgPC0KICBmdWxsX2pvaW4oCiAgICBjYXJkaW9fcGVyX3NpdGUsCiAgICBjYXJkaW9fcG9seW9taWNzX3Blcl9zaXRlLAogICAgYnkgPSBjKAogICAgICAidmlydXMiLAogICAgICAic2VnIiwKICAgICAgInNpdGUiLAogICAgICAiY292ZXJhZ2UiLAogICAgICAibl9zaXRlcyIsCiAgICAgICJTYW1wbGVfaWQiLAogICAgICAiQmFja2dyb3VuZCIsCiAgICAgICJWaXJhbC5sb2FkIiwKICAgICAgIm1hcHBlciIsCiAgICAgICJ0eXBlIgogICAgKQogICkKCmNhcmRpb19URV9wb2x5b21pY3MkVmlyYWwubG9hZCA8LSBjYXJkaW9fVEVfcG9seW9taWNzJFZpcmFsLmxvYWQgJT4lCiAgcmVwbGFjZV9uYSguLCAwKQoKZHJvcHMgPC0KICBjKAogICAgIlJOQS1Nc3AtcDEiLAogICAgIlJOQS1Nc3AtcDMiLAogICAgIlJOQS1Nc3AtcDQiLAogICAgIlJOQS1Nc3AtcDUiLAogICAgIlJOQS1Nc3AtcDYiLAogICAgIlJOQS1Nc3AtcDciLAogICAgIlJOQS1Nc3AtcDkiCiAgKQoKY2FyZGlvX1RFX3BvbHlvbWljcyA8LSBjYXJkaW9fVEVfcG9seW9taWNzICU+JQogIGZpbHRlcighU2FtcGxlX2lkICVpbiUgZHJvcHMpCgpjYXJkaW9fVEVfcG9seW9taWNzJFNhbXBsZV9pZCA8LSBjYXJkaW9fVEVfcG9seW9taWNzJFNhbXBsZV9pZCAlPiUKICBjYXNlX21hdGNoKCJSTkEtTXNwLXAyIiB+ICJNMSIsCiAgICAgICAgICAgICAiUk5BLU1zcC1wOCIgfiAiTTIiLAogICAgICAgICAgICAgLmRlZmF1bHQgPSBjYXJkaW9fVEVfcG9seW9taWNzJFNhbXBsZV9pZCkKCmNhcmRpb19URV9wb2x5b21pY3MkQmFja2dyb3VuZCA8LSBjYXJkaW9fVEVfcG9seW9taWNzJEJhY2tncm91bmQgJT4lCiAgY2FzZV9tYXRjaCgiUzE4IiB+ICJNMSIsCiAgICAgICAgICAgICAiUzQzIiB+ICJNMiIsCiAgICAgICAgICAgICAicDIiIH4gIk0xIiwKICAgICAgICAgICAgICJwOCIgfiAiTTIiLAogICAgICAgICAgICAgLmRlZmF1bHQgPSBjYXJkaW9fVEVfcG9seW9taWNzJEJhY2tncm91bmQpCgpwZXJzaXRlX2JvdGggPC0gcmJpbmQoa29idV9wZXJfc2l0ZSwgY2FyZGlvX1RFX3BvbHlvbWljcykKCnBlcnNpdGVfYm90aCR0eXBlIDwtIHBlcnNpdGVfYm90aCR0eXBlICU+JQogIGNhc2VfbWF0Y2goImRlZHVwX1RFIiB+ICJkZWR1cCIsCiAgICAgICAgICAgICAiZGVkdXBfcG9seW9taWNzIiB+ICJkZWR1cCIsCiAgICAgICAgICAgICAuZGVmYXVsdCA9IHBlcnNpdGVfYm90aCR0eXBlKQoKI1RFIGRhdGEgb25seSAtIGNvbXBhcmUgY292ZXJhZ2UgYmV0d2VlbiBiYWNrZ3JvdW5kcy92aXJhbCBsb2FkcwoKY29sczIgPC0gYygiI0JCNTU2NiIsICIjMDA0NDg4IikKCmNvdmVyYWdlX2xhYmVscyA8LSBjKAogICIxMDAiID0gIjEwXnsyfSIsCiAgIjEwMDAiID0gIjEwXnszfSIsCiAgIjEwMDAwMCIgPSAiMTBeezV9IiwKICAiMCIgPSAiU2hvdGd1biIsCiAgIktvYnV2aXJ1cyIgPSAiS29idXZpcnVzIiwKICAiQ2FyZGlvdmlydXMiID0gIkNhcmRpb3ZpcnVzIgopCgpjb3ZlcmFnZV9sYWJlbHMyIDwtIGMoCiAgIjEwMCIgPSAiMTBeezJ9IiwKICAiMTAwMCIgPSAiMTBeezN9IiwKICAiMTAwMDAwIiA9ICIxMF57NX0iLAogICIwIiA9ICJTaG90Z3VuIiwKICAiQSIgPSAiQSIsCiAgIkIiID0gIkIiLAogICJDIiA9ICJDIiwKICAiRCIgPSAiRCIsCiAgIkYiID0gIkYiLAogICJHIiA9ICJHIiwKICAiSCIgPSAiSCIsCiAgIkkiID0gIkkiLAogICJKIiA9ICJKIiwKICAiSyIgPSAiSyIsCiAgIkwiID0gIkwiLAogICJNIiA9ICJNIiwKICAiTiIgPSAiTiIsCiAgIk8iID0gIk8iLAogICJQIiA9ICJQIiwKICAiTUVfUDEiID0gIk0xIiwKICAiTUVfUDIiID0gIk0yIgopCgprb2J1X2NvdmVyYWdlIDwtIGtvYnVfcGVyX3NpdGUgJT4lCiAgZmlsdGVyKG1hcHBlciA9PSAiYm93dGllMiIpICU+JQogIGZpbHRlcih0eXBlID09ICJkZWR1cCIpICU+JQogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpICU+JQogIGdyb3VwX2J5KFNhbXBsZV9pZCwgVmlyYWwubG9hZCwgQmFja2dyb3VuZCkgJT4lCiAgZmlsdGVyKGNvdmVyYWdlID4gMCkgJT4lCiAgc3VtbWFyaXNlKGdlbm9tZV9jb3ZlcmFnZSA9IG4oKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfY292ZXJhZ2UgPSBnZW5vbWVfY292ZXJhZ2UgLyA4NDY3KSAlPiUKICBtdXRhdGUodmlydXMgPSAiS29idXZpcnVzIikKCmNhcmRpb19jb3ZlcmFnZSA8LSBjYXJkaW9fVEVfcG9seW9taWNzICU+JQogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpICU+JQogIGdyb3VwX2J5KFNhbXBsZV9pZCwgVmlyYWwubG9hZCwgQmFja2dyb3VuZCkgJT4lCiAgZmlsdGVyKGNvdmVyYWdlID4gMCkgJT4lCiAgc3VtbWFyaXNlKGdlbm9tZV9jb3ZlcmFnZSA9IG4oKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfY292ZXJhZ2UgPSBnZW5vbWVfY292ZXJhZ2UgLyA2OTQ1KSAlPiUKICBtdXRhdGUodmlydXMgPSAiQ2FyZGlvdmlydXMiKQoKY292ZXJhZ2VfYm90aCA8LSByYmluZChrb2J1X2NvdmVyYWdlLCBjYXJkaW9fY292ZXJhZ2UpCgpjb3ZlcmFnZV9ib3RoJFZpcmFsLmxvYWQgPC0gZmFjdG9yKGNvdmVyYWdlX2JvdGgkVmlyYWwubG9hZCwgbGFiZWxzID0gYygiU2hvdGd1biIsCiAgICAiMTBeezJ9IiwgCiAgICAiMTBeezN9IiwgCiAgICAiMTBeezV9IgogICAgKSkKCmBgYAoKIyMjIyAqKiogRmluYWwgcGxvdCAqKioKYGBge3J9Cgpjb3ZlcmFnZV9ib3RoICU+JQogIGdncGxvdChhZXMoeCA9IFNhbXBsZV9pZCwgeSA9IHBlcmNlbnRfY292ZXJhZ2UsIGNvbG9yID0gQmFja2dyb3VuZCkpICsKICBnZW9tX3BvaW50KCkgKwogIHlsYWIoIkdlbm9tZSBjb3ZlcmFnZSIpICsKICB4bGFiKCJTYW1wbGUgSUQiKSArCiAgZmFjZXRfZ3JpZCh2aXJ1cyB+IChWaXJhbC5sb2FkKSwKICAgICAgICAgICAgIHNjYWxlcyA9ICJmcmVlX3giLAogICAgICAgICAgICAgbGFiZWwgPSBsYWJlbF9wYXJzZWQpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sczIsIGxhYmVscyA9IGMoIk0xIiwgIk0yIikpICsKIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArIAogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDEpKQoKI1BERgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlX1MxNC5wZGYiLCAKICAgICAgIHdpZHRoID0gOCwgCiAgICAgICBoZWlnaHQgPSA0KQoKI1BORwpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QTkcvRmlndXJlX1MxNC5wbmciLCAKICAgICAgIHdpZHRoID0gOCwgCiAgICAgICBoZWlnaHQgPSA0KQoKYGBgCgoKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIyBGaWd1cmUgUzE1CgpgYGB7ciwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KCiNwZXIgc2l0ZSBnZW5vbWUgY292ZXJhZ2UgLSBLb2J1CgpwZXJzaXRlX2JvdGgkVmlyYWwubG9hZCA8LSBmYWN0b3IocGVyc2l0ZV9ib3RoJFZpcmFsLmxvYWQsIGxhYmVscyA9IGMoIlNob3RndW4iLAogICAgIjEwXnsyfSIsIAogICAgIjEwXnszfSIsIAogICAgIjEwXns1fSIKICAgICkpCgpwZXJzaXRlX2JvdGgkVmlyYWwubG9hZCA8LSBmYWN0b3IocGVyc2l0ZV9ib3RoJFZpcmFsLmxvYWQsIGxldmVscyA9IGMoCiAgICAiMTBeezJ9IiwgCiAgICAiMTBeezN9IiwgCiAgICAiMTBeezV9IiwKICAgICJTaG90Z3VuIgogICAgKSkKCnBlcnNpdGVfYm90aCB8PgogIGZpbHRlcih2aXJ1cyA9PSAiazk3XzE5OTcxIikgfD4KICBmaWx0ZXIobWFwcGVyID09ICJib3d0aWUyIikgfD4KICBmaWx0ZXIodHlwZSA9PSAiZGVkdXAiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBzaXRlLAogICAgeSA9IChjb3ZlcmFnZSksCiAgICBmaWxsID0gQmFja2dyb3VuZAogICkpICsKICBnZW9tX2NvbCgpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKyAgIAogIGZhY2V0X3dyYXAoVmlyYWwubG9hZCB+IFNhbXBsZV9pZCwgbGFiZWxsZXIgPSBsYWJlbF9wYXJzZWQpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xzMiwgbGFiZWxzID0gYygiTTEiLCAiTTIiKSkgKwogIHlsYWIoIkNvdmVyYWdlIikgKwogIHhsYWIoIiIpICsKICBnZ3RpdGxlKCJLb2J1dmlydXMiKSArCiAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKQoKYGBgCgojIyMjICoqKiBGaW5hbCBwbG90ICoqKgpgYGB7cn0KI1BERgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlX1MxNS5wZGYiLAogICAgICAgd2lkdGg9MTIsCiAgICAgICBoZWlnaHQ9NykKCiNQTkcKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUG5nL0ZpZ3VyZV9TMTUucG5nIiwKICAgICAgIHdpZHRoPTEyLAogICAgICAgaGVpZ2h0PTcpCgpgYGAKCiMjIyMgRmlndXJlIFMxNgpgYGB7ciwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KCiNwZXIgc2l0ZSBnZW5vbWUgY292ZXJhZ2UgLSBDYXJkaW8KCnBlcnNpdGVfYm90aCB8PgogIGZpbHRlcih2aXJ1cyA9PSAiY2FyZGlvdmlydXMiKSB8PgogIGZpbHRlcihtYXBwZXIgPT0gImJvd3RpZTIiKSB8PgogIGZpbHRlcih0eXBlID09ICJkZWR1cCIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IHNpdGUsCiAgICB5ID0gY292ZXJhZ2UsCiAgICBmaWxsID0gQmFja2dyb3VuZAogICkpICsKICBnZW9tX2NvbCgpICsKICBmYWNldF93cmFwKFZpcmFsLmxvYWQgfiBTYW1wbGVfaWQsIGxhYmVsbGVyID0gbGFiZWxfcGFyc2VkKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sczIsIGxhYmVscyA9IGMoIk0xIiwgIk0yIikpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHlsYWIoIkNvdmVyYWdlIikgKwogIHhsYWIoIiIpICsKICBnZ3RpdGxlKCJDYXJkaW92aXJ1cyIpICsKICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZXM6OmxhYmVsX21hdGgoKSkpCmBgYAoKIyMjIyAqKiogRmluYWwgcGxvdCAqKioKYGBge3J9CgojUERGCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BERi9GaWd1cmVfUzE2LnBkZiIsCiAgICAgICB3aWR0aD0xMiwKICAgICAgIGhlaWdodD03KQoKCiNQTkcKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUE5HL0ZpZ3VyZV9TMTYucG5nIiwKICAgICAgIHdpZHRoPTEyLAogICAgICAgaGVpZ2h0PTcpCmBgYAoK